music playergd --cachedgd --cached!
This commit is contained in:
parent
b806a04da1
commit
52a8c6e659
|
@ -15,7 +15,7 @@
|
|||
✔ Save a preferred city for each user for time and weather [2 pts] @done (17-03-27 00:53)
|
||||
✔ Look up a random joke [2 pts] @done (17-03-27 00:53)
|
||||
☐ Send an image from Google Image Search Results [5 pts]
|
||||
☐ Stream music from YouTube to a voice channel [10 pts]
|
||||
✔ Stream music from YouTube to a voice channel [10 pts] @done (17-04-30 23:56)
|
||||
✔ Create and vote on polls [5 pts] @done (17-04-18 23:22)
|
||||
☐ Hangman [5 pts]
|
||||
✔ TicTacToe [5 pts] @done (17-04-24 02:04)
|
||||
|
|
10
bot
10
bot
|
@ -1,14 +1,16 @@
|
|||
#!/bin/bash
|
||||
|
||||
source .env
|
||||
|
||||
# pid=$(ps -ef | grep BenBot | grep -v grep | awk '{print $2}')
|
||||
pid=$(pidof BenBot)
|
||||
pid=$(pidof $WHICHBOT)
|
||||
|
||||
case "$1" in
|
||||
|
||||
nohup)
|
||||
if [ $pid ]; then
|
||||
echo "starting BenBot in background (nohup)"
|
||||
nohup php run.php > bot.out 2> bot.err < /dev/null &
|
||||
nohup php run.php $WHICHBOT > bot.out 2> bot.err < /dev/null &
|
||||
else
|
||||
echo "BenBot already running"
|
||||
fi
|
||||
|
@ -55,7 +57,7 @@ case "$1" in
|
|||
;;
|
||||
|
||||
cloc)
|
||||
cloc --exclude-dir=vendor --include-lang=PHP .
|
||||
cloc --exclude-dir=vendor --by-file-by-lang .
|
||||
;;
|
||||
|
||||
sync)
|
||||
|
@ -70,7 +72,7 @@ case "$1" in
|
|||
kill $pid
|
||||
fi
|
||||
echo "starting BenBot in background (nohup)"
|
||||
nohup php run.php > bot.out 2> bot.err < /dev/null &
|
||||
nohup php run.php $WHICHBOT > bot.out 2> bot.err < /dev/null &
|
||||
;;
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Uses more "sensible" (for English keyboards) key mapping for the
|
||||
# Jerusalem figlet font.
|
||||
|
||||
tr "abgdhvzctykflmonieypujwqrsx,.;/'" "tcdsvuzjyhflknobixgp;m.era,'/\`qw" | figlet -f jerusalem $*
|
|
@ -4,8 +4,9 @@
|
|||
ini_set('display_errors', true);
|
||||
error_reporting(-1);
|
||||
|
||||
$procname = $argv[1] ?? "BenBot";
|
||||
|
||||
if (!cli_set_process_title("BenBot")) {
|
||||
if (!cli_set_process_title($procname)) {
|
||||
die("couldn't set process title");
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ final class Debug
|
|||
],
|
||||
]);
|
||||
|
||||
self::$bot->registerCommand('edittest', [__CLASS__, 'editMsgTest']);
|
||||
|
||||
|
||||
echo __CLASS__ . " registered", PHP_EOL;
|
||||
}
|
||||
|
@ -264,4 +266,22 @@ final class Debug
|
|||
}
|
||||
|
||||
|
||||
public static function editMsgTest($msg, $args)
|
||||
{
|
||||
Utils::send($msg, count($msg->channel->guild->channels))->then(function ($result) {
|
||||
$result->content = 'ben is best';
|
||||
self::$bot->loop->addTimer(3, function ($timer) use ($result) {
|
||||
$result->channel->messages->save($result)->then(function ($res) {
|
||||
self::$bot->loop->addTimer(2, function ($timer) use ($res) {
|
||||
$res->channel->messages->delete($res);
|
||||
});
|
||||
}, function ($e) {
|
||||
echo $e->getMessage(), PHP_EOL;
|
||||
echo $e->getTraceAsString(), PHP_EOL;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ final class Hangman
|
|||
public static function startGame($msg, $args)
|
||||
{
|
||||
return "```" . self::$gallows . "```";
|
||||
return "not done yet";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ namespace BenBot\Commands;
|
|||
|
||||
use BenBot\Utils;
|
||||
|
||||
use React\Promise\Deferred;
|
||||
|
||||
use Discord\Helpers\Process;
|
||||
use Discord\Voice\VoiceClient;
|
||||
use Discord\Parts\Channel\Channel;
|
||||
|
@ -11,11 +13,14 @@ final class Music
|
|||
{
|
||||
|
||||
private static $bot;
|
||||
private static $voiceclients;
|
||||
|
||||
public static function register(&$that)
|
||||
{
|
||||
self::$bot = $that;
|
||||
|
||||
self::$voiceclients = [];
|
||||
|
||||
self::$bot->registerCommand('play', [__CLASS__, 'playFromYouTube'], [
|
||||
'description' => 'plays',
|
||||
'usage' => '<yt ID|URL|search>',
|
||||
|
@ -23,7 +28,15 @@ final class Music
|
|||
'yt',
|
||||
],
|
||||
]);
|
||||
|
||||
self::$bot->registerCommand('pause', [__CLASS__, 'pauseAudio'], [
|
||||
'description' => 'pauses the currently playing song',
|
||||
]);
|
||||
self::$bot->registerCommand('resume', [__CLASS__, 'resumeAudio'], [
|
||||
'description' => 'resumes a paused song',
|
||||
]);
|
||||
self::$bot->registerCommand('stop', [__CLASS__, 'stopAudio'], [
|
||||
'description' => 'stops the currently playing song',
|
||||
]);
|
||||
self::$bot->registerCommand('mytype', [__CLASS__, 'playTest'], [
|
||||
'description' => 'ur just my type',
|
||||
]);
|
||||
|
@ -32,15 +45,6 @@ final class Music
|
|||
echo __CLASS__ . " registered", PHP_EOL;
|
||||
}
|
||||
|
||||
public static function playSong($msg, $args)
|
||||
{
|
||||
self::$bot->joinVoiceChannel($msg->channel)->then(function (VoiceClient $vc) {
|
||||
echo "joined voice channel", PHP_EOL;
|
||||
$vc->playFile(self::$bot->dir . "/music/mytype.m4a");
|
||||
}, function ($e) {
|
||||
echo "there was an error joining the voice channel: {$e->getMessage()}", PHP_EOL, $e->getTraceAsString(), PHP_EOL;
|
||||
});
|
||||
}
|
||||
|
||||
public static function playTest($msg, $args)
|
||||
{
|
||||
|
@ -61,23 +65,86 @@ final class Music
|
|||
|
||||
public static function playFromYouTube($msg, $args)
|
||||
{
|
||||
$channel = null;
|
||||
foreach ($msg->channel->guild->channels as $chnl) {
|
||||
if ($chnl->type != Channel::TYPE_VOICE) {
|
||||
continue;
|
||||
}
|
||||
// print_r($chnl);
|
||||
if ($chnl->members->get('id', $msg->author->id)) {
|
||||
$channel = $chnl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$channel = self::getVoiceChannel($msg);
|
||||
print_r($channel);
|
||||
if (!$channel instanceof Channel) {
|
||||
return "you're not in a voice channel, silly";
|
||||
}
|
||||
|
||||
$cmd = "youtube-dl --extract-audio --audio-format mp3 --audio-quality 0 -o - ";
|
||||
if (isset(self::$voiceclients[$msg->channel->guild->id]) && self::$voiceclients[$msg->channel->guild->id] instanceof VoiceClient) {
|
||||
self::$voiceclients[$msg->channel->guild->id]->stop();
|
||||
self::getVideoJSON($args)->then(function ($json) use ($msg) {
|
||||
Utils::send($msg, "preparing...")->then(function ($statusmsg) use ($msg, $json) {
|
||||
self::downloadAudio($json)->then(function ($file) use ($statusmsg, $msg) {
|
||||
$statusmsg->channel->messages->delete($statusmsg);
|
||||
self::$voiceclients[$msg->channel->guild->id]->playFile(self::$bot->dir . "/music/$file")->then(function () {
|
||||
self::$voiceclients[$msg->channel->guild->id]->close();
|
||||
}, function ($e) {
|
||||
echo $e->getMessage(), PHP_EOL;
|
||||
echo $e->getTraceAsString(), PHP_EOL;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
self::getVideoJSON($args)->then(function ($json) use ($channel, $msg) {
|
||||
Utils::send($msg, "preparing...")->then(function ($statusmsg) use ($channel, $msg, $json) {
|
||||
self::downloadAudio($json)->then(function ($file) use ($channel, $statusmsg, $msg) {
|
||||
$statusmsg->channel->messages->delete($statusmsg);
|
||||
self::$bot->joinVoiceChannel($channel)->then(function (VoiceClient $vc) use ($file, $msg) {
|
||||
self::$voiceclients[$msg->channel->guild->id] = $vc;
|
||||
$vc->playFile(self::$bot->dir . "/music/$file")->then(function () use ($vc) {
|
||||
$vc->close();
|
||||
}, function ($e) {
|
||||
echo $e->getMessage(), PHP_EOL;
|
||||
echo $e->getTraceAsString(), PHP_EOL;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static function pauseAudio($msg, $args)
|
||||
{
|
||||
if (self::$voiceclients[$msg->channel->guild->id] instanceof VoiceClient) {
|
||||
self::$voiceclients[$msg->channel->guild->id]->pause();
|
||||
return "paused";
|
||||
} else {
|
||||
return "not playing...";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function resumeAudio($msg, $args)
|
||||
{
|
||||
if (self::$voiceclients[$msg->channel->guild->id] instanceof VoiceClient) {
|
||||
self::$voiceclients[$msg->channel->guild->id]->unpause();
|
||||
return "resuming";
|
||||
} else {
|
||||
return "not stopped...";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static function stopAudio($msg, $args)
|
||||
{
|
||||
if (self::$voiceclients[$msg->channel->guild->id] instanceof VoiceClient) {
|
||||
self::$voiceclients[$msg->channel->guild->id]->stop();
|
||||
return "stopped";
|
||||
} else {
|
||||
return "not playing...";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static function getVideoJSON($args)
|
||||
{
|
||||
$deferred = new Deferred();
|
||||
|
||||
$cmd = "youtube-dl --dump-single-json ";
|
||||
if ($args[0] != "") {
|
||||
if (strlen($args[0]) === 11 || strpos($args[0], "http") !== false) {
|
||||
// is yt vid ID or URL
|
||||
|
@ -86,27 +153,79 @@ final class Music
|
|||
$query = implode(" ", $args);
|
||||
$cmd .= "'ytsearch:$query'";
|
||||
}
|
||||
} else {
|
||||
return "gotta pick something to play, silly";
|
||||
}
|
||||
|
||||
echo $cmd, PHP_EOL;
|
||||
|
||||
self::$bot->joinVoiceChannel($channel)->then(function (VoiceClient $vc) use ($cmd) {
|
||||
$process = new Process($cmd);
|
||||
$process->start(self::$bot->loop);
|
||||
echo "process started", PHP_EOL;
|
||||
$vc->playRawStream($process->stdout)->then(function () use ($vc) {
|
||||
echo "stream done playing", PHP_EOL;
|
||||
$vc->close();
|
||||
}, function ($e) {
|
||||
echo $e->getMessage(), PHP_EOL;
|
||||
echo $e->getTraceAsString(), PHP_EOL;
|
||||
});
|
||||
}, function ($e) {
|
||||
echo $e->getMessage(), PHP_EOL;
|
||||
echo $e->getTraceAsString(), PHP_EOL;
|
||||
$process = new Process($cmd);
|
||||
$process->on('exit', function ($exitcode, $termsig) use (&$data, $deferred) {
|
||||
if (intval($exitcode) === 1) {
|
||||
$deferred->reject("invalid url");
|
||||
} else {
|
||||
$deferred->resolve(json_decode($data));
|
||||
}
|
||||
echo "$exitcode, $termsig", PHP_EOL;
|
||||
});
|
||||
self::$bot->loop->addTimer(0.001, function ($timer) use (&$data, $deferred, $process) {
|
||||
$process->start(self::$bot->loop);
|
||||
$process->stdout->on('data', function ($output) use (&$data) {
|
||||
$data .= $output;
|
||||
});
|
||||
});
|
||||
|
||||
return $deferred->promise();
|
||||
}
|
||||
|
||||
|
||||
private static function downloadAudio($result)
|
||||
{
|
||||
$deferred = new Deferred();
|
||||
|
||||
$json = $result->entries[0];
|
||||
$url = escapeshellarg($json->webpage_url);
|
||||
$filename = $json->id . '-' . md5($json->title) . '-' . $json->duration;
|
||||
|
||||
foreach (scandir(self::$bot->dir . '/music') as $file) {
|
||||
// check if we've already downloaded the file!
|
||||
if (pathinfo($file, PATHINFO_FILENAME) === $filename) {
|
||||
$deferred->resolve($file);
|
||||
return $deferred->promise();
|
||||
}
|
||||
}
|
||||
|
||||
$file = escapeshellarg(self::$bot->dir . "/music/$filename.%(ext)s");
|
||||
|
||||
$cmd = "youtube-dl --extract-audio --audio-format mp3 --audio-quality 0 --restrict-filenames --no-check-certificate --no-warnings --source-address 0.0.0.0 -o $file $url";
|
||||
echo $cmd, PHP_EOL;
|
||||
|
||||
$process = new Process($cmd);
|
||||
$process->on('exit', function ($exitcode, $termsig) use ($deferred, $filename) {
|
||||
if (intval($exitcode) !== 0) {
|
||||
$deferred->reject('error downloading video');
|
||||
} else {
|
||||
foreach (scandir(self::$bot->dir . '/music') as $file) {
|
||||
if (pathinfo($file, PATHINFO_FILENAME) === $filename) {
|
||||
$deferred->resolve($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
self::$bot->loop->addTimer(0.001, function ($timer) use ($deferred, $process) {
|
||||
$process->start(self::$bot->loop);
|
||||
});
|
||||
|
||||
return $deferred->promise();
|
||||
}
|
||||
|
||||
|
||||
private static function getVoiceChannel($msg)
|
||||
{
|
||||
foreach ($msg->channel->guild->channels->getAll('type', Channel::TYPE_VOICE) as $voicechannel) {
|
||||
if (!empty($voicechannel->members->get('user_id', $msg->author->id))) {
|
||||
return $voicechannel;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue