mirror of
https://github.com/danog/MadelineProto.git
synced 2024-11-26 19:04:40 +01:00
Fix playing and converting VoIP audio from a stream
This commit is contained in:
parent
c37df506ad
commit
1d989eeabe
@ -56,13 +56,13 @@ Tip: if you receive an error (or nothing), [send us](https://t.me/pwrtelegramgro
|
||||
|
||||
The following open source projects were created using MadelineProto: you can directly install them, or explore the source code as direct examples on how to use MadelineProto's many features!
|
||||
|
||||
<!-- * [magnaluna webradio](https://magna.madelineproto.xyz) - Multifeatured Telegram VoIP webradio -->
|
||||
* [magnaluna webradio](https://magna.madelineproto.xyz) - Multifeatured Telegram VoIP webradio
|
||||
* [TelegramApiServer](https://github.com/xtrime-ru/TelegramApiServer) - Fast, simple, async php telegram api server: an HTTP JSON API for MadelineProto!
|
||||
* [`tgstories_dl_bot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/tgstories_dl_bot.php) - Source code of [@tgstories_dl_bot](https://t.me/tgstories_dl_bot) - Bot to download any Telegram Story!
|
||||
* [`downloadRenameBot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/downloadRenameBot.php) - Download files by URL and rename Telegram files using this async parallelized bot!
|
||||
* [`secret_bot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/secret_bot.php) - Secret chat bot!
|
||||
* [`pipesbot.php`](https://github.com/danog/pipesbot) - Creating inline bots and using other inline bots via a userbot!
|
||||
* [`bot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/bot.php) - Examples for sending normal messages, downloading any media!
|
||||
* [`bot.php`](https://github.com/danog/MadelineProto/blob/v8/examples/bot.php) - Examples for how to use filters, updates, get download links for any file, Telegram Stories and much more!
|
||||
|
||||
Want to add your own open-source project to this list? [Click here!](https://docs.madelineproto.xyz/FOSS.html)
|
||||
|
||||
@ -882,8 +882,8 @@ Want to add your own open-source project to this list? [Click here!](https://doc
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.uploadImportedMedia.html" name="messages.uploadImportedMedia">Upload a media file associated with an imported chat, click here for more info »: messages.uploadImportedMedia</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/messages.uploadEncryptedFile.html" name="messages.uploadEncryptedFile">Upload encrypted file and associate it to a secret chat: messages.uploadEncryptedFile</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadfromurl-string-filecallbackinterface-url-int-size-0-string-filename-callable-cb-null-bool-encrypted-false-mixed" name="uploadFromUrl">Upload file from URL: uploadFromUrl</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadfromcallable-mixed-callable-int-size-string-mime-string-filename-callable-cb-null-bool-seekable-true-bool-encrypted-false-mixed" name="uploadFromCallable">Upload file from callable: uploadFromCallable</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadfromstream-mixed-stream-int-size-string-mime-string-filename-callable-cb-null-bool-encrypted-false-mixed" name="uploadFromStream">Upload file from stream: uploadFromStream</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadfromcallable-mixed-callable-int-size-0-string-mime-application-octet-stream-string-filename-callable-cb-null-bool-seekable-true-bool-encrypted-false-mixed" name="uploadFromCallable">Upload file from callable: uploadFromCallable</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadfromstream-mixed-stream-int-size-0-string-mime-application-octet-stream-string-filename-callable-cb-null-bool-encrypted-false-mixed" name="uploadFromStream">Upload file from stream: uploadFromStream</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#uploadencrypted-filecallbackinterface-string-array-file-string-filename-callable-cb-null-mixed" name="uploadEncrypted">Upload file to secret chat: uploadEncrypted</a>
|
||||
* <a href="https://docs.madelineproto.xyz/PHP/danog/MadelineProto/API.html#upload-filecallbackinterface-localfile-remoteurl-botapifileid-string-array-resource-file-string-filename-callable-cb-null-bool-encrypted-false-mixed" name="upload">Upload file: upload</a>
|
||||
* <a href="https://docs.madelineproto.xyz/API_docs/methods/account.uploadRingtone.html" name="account.uploadRingtone">Upload notification sound, use account.saveRingtone to convert it and add it to the list of saved notification sounds: account.uploadRingtone</a>
|
||||
|
@ -73,8 +73,7 @@
|
||||
"amphp/http-server": "^3",
|
||||
"leproxy/leproxy": "^0.2.2",
|
||||
"revolt/event-loop-adapter-react": "^1",
|
||||
"dg/bypass-finals": "dev-master",
|
||||
"roave/backward-compatibility-check": "^8.3"
|
||||
"dg/bypass-finals": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-primemodule": "Install the primemodule and FFI extensions to speed up MadelineProto (https://prime.madelineproto.xyz)",
|
||||
|
@ -21,6 +21,7 @@
|
||||
use danog\MadelineProto\EventHandler;
|
||||
use danog\MadelineProto\FileCallback;
|
||||
use danog\MadelineProto\Logger;
|
||||
use danog\MadelineProto\ParseMode;
|
||||
use danog\MadelineProto\RPCErrorException;
|
||||
use danog\MadelineProto\Settings;
|
||||
use League\Uri\Contracts\UriException;
|
||||
@ -63,30 +64,12 @@ class MyEventHandler extends EventHandler
|
||||
return [self::ADMIN];
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to allow uploads.
|
||||
*/
|
||||
private $UPLOAD;
|
||||
|
||||
/**
|
||||
* Array of media objects.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $states = [];
|
||||
public function onStart(): void
|
||||
{
|
||||
$this->adminId = $this->getInfo(self::ADMIN)['bot_api_id'];
|
||||
}
|
||||
/**
|
||||
* Handle updates from channels and supergroups.
|
||||
*
|
||||
* @param array $update Update
|
||||
*/
|
||||
public function onUpdateNewChannelMessage(array $update): void
|
||||
{
|
||||
//$this->onUpdateNewMessage($update);
|
||||
}
|
||||
/**
|
||||
* Handle updates from users.
|
||||
*
|
||||
@ -109,10 +92,6 @@ class MyEventHandler extends EventHandler
|
||||
if ($update['message']['message'] === '/start') {
|
||||
return $this->messages->sendMessage(['peer' => $peerId, 'message' => self::START, 'parse_mode' => 'Markdown', 'reply_to_msg_id' => $messageId]);
|
||||
}
|
||||
if ($update['message']['message'] === '/report' && $peerId === $this->adminId) {
|
||||
$this->reportMemoryProfile();
|
||||
return;
|
||||
}
|
||||
if (isset($update['message']['media']['_']) && $update['message']['media']['_'] !== 'messageMediaWebPage') {
|
||||
$this->messages->sendMessage(['peer' => $peerId, 'message' => 'Give me a new name for this file: ', 'reply_to_msg_id' => $messageId]);
|
||||
$this->states[$peerId] = $update['message']['media'];
|
||||
@ -175,7 +154,7 @@ class MyEventHandler extends EventHandler
|
||||
],
|
||||
],
|
||||
message: 'Powered by @MadelineProto!',
|
||||
parse_mode: 'Markdown',
|
||||
parse_mode: ParseMode::MARKDOWN,
|
||||
);
|
||||
|
||||
if (in_array($peer['type'], ['channel', 'supergroup'])) {
|
||||
|
@ -688,7 +688,6 @@
|
||||
<code>downloadToStream</code>
|
||||
<code>end</code>
|
||||
<code>phoneLogin</code>
|
||||
<code>requestCall</code>
|
||||
<code>requestSecretChat</code>
|
||||
<code>start</code>
|
||||
<code>tdToTdcli</code>
|
||||
@ -1203,15 +1202,6 @@
|
||||
<code>logger</code>
|
||||
<code>start</code>
|
||||
</PossiblyNullReference>
|
||||
<PropertyNotSetInConstructor>
|
||||
<code>$channelParticipants</code>
|
||||
<code>$logger</code>
|
||||
<code>$minDatabase</code>
|
||||
<code>$session</code>
|
||||
<code>$snitch</code>
|
||||
<code>$wrapper</code>
|
||||
<code>MTProto</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<PropertyTypeCoercion>
|
||||
<code><![CDATA[$this->sanitizeReportPeers($userOrId)]]></code>
|
||||
</PropertyTypeCoercion>
|
||||
@ -1363,9 +1353,6 @@
|
||||
<DocblockTypeContradiction>
|
||||
<code><![CDATA[$fingerprint !== $messageMedia['key_fingerprint']]]></code>
|
||||
</DocblockTypeContradiction>
|
||||
<MissingClosureReturnType>
|
||||
<code>static function (int $part_num) use ($size, $file_id, $part_total_num, $part_size, $callable, $ige) {</code>
|
||||
</MissingClosureReturnType>
|
||||
<MissingParamType>
|
||||
<code>$data</code>
|
||||
<code>$media</code>
|
||||
@ -1423,6 +1410,9 @@
|
||||
<RedundantCondition>
|
||||
<code><![CDATA[$fingerprint !== $messageMedia['key_fingerprint']]]></code>
|
||||
</RedundantCondition>
|
||||
<TooManyArguments>
|
||||
<code>$cb(100, $speed, $time)</code>
|
||||
</TooManyArguments>
|
||||
<TypeDoesNotContainType>
|
||||
<code><![CDATA[$res['ext'] === '']]></code>
|
||||
<code><![CDATA[$res['ext'] === '']]></code>
|
||||
@ -1457,7 +1447,6 @@
|
||||
<code><![CDATA[$_SERVER['REQUEST_METHOD']]]></code>
|
||||
</PossiblyUndefinedArrayOffset>
|
||||
<PossiblyUndefinedMethod>
|
||||
<code>read</code>
|
||||
<code>seek</code>
|
||||
<code>seek</code>
|
||||
</PossiblyUndefinedMethod>
|
||||
@ -1488,12 +1477,8 @@
|
||||
<file src="src/MTProtoTools/PeerDatabase.php">
|
||||
<InvalidPropertyAssignmentValue>
|
||||
<code><![CDATA[$this->pendingDb]]></code>
|
||||
<code><![CDATA[$this->pendingDb]]></code>
|
||||
<code><![CDATA[$this->pendingDb]]></code>
|
||||
</InvalidPropertyAssignmentValue>
|
||||
<PossiblyNullArgument>
|
||||
<code>$id</code>
|
||||
<code>$id</code>
|
||||
<code><![CDATA[$this->API->getIdInternal($full)]]></code>
|
||||
<code><![CDATA[$this->API->getIdInternal($full)]]></code>
|
||||
<code><![CDATA[$this->API->getIdInternal($id)]]></code>
|
||||
@ -1506,8 +1491,6 @@
|
||||
<code><![CDATA[$this->fullDb]]></code>
|
||||
<code><![CDATA[$this->fullDb]]></code>
|
||||
<code><![CDATA[$this->pendingDb]]></code>
|
||||
<code><![CDATA[$this->pendingDb]]></code>
|
||||
<code><![CDATA[$this->pendingDb]]></code>
|
||||
</PossiblyNullArrayOffset>
|
||||
<PropertyNotSetInConstructor>
|
||||
<code>$db</code>
|
||||
@ -2248,11 +2231,6 @@
|
||||
<code><![CDATA[$API->getSelf()['id']]]></code>
|
||||
</PossiblyInvalidArrayAccess>
|
||||
</file>
|
||||
<file src="src/VoIP/AuthKeyHandler.php">
|
||||
<MissingReturnType>
|
||||
<code>requestCall</code>
|
||||
</MissingReturnType>
|
||||
</file>
|
||||
<file src="src/VoIP/Endpoint.php">
|
||||
<MissingParamType>
|
||||
<code>$stream</code>
|
||||
@ -2276,9 +2254,6 @@
|
||||
</PossiblyUndefinedVariable>
|
||||
</file>
|
||||
<file src="src/VoIPController.php">
|
||||
<ArgumentTypeCoercion>
|
||||
<code>$stream</code>
|
||||
</ArgumentTypeCoercion>
|
||||
<InaccessibleProperty>
|
||||
<code><![CDATA[$this->authKey]]></code>
|
||||
<code><![CDATA[$this->authKey]]></code>
|
||||
|
@ -531,6 +531,7 @@ final class Blacklist {
|
||||
\fwrite($handle, "use __PHP_Incomplete_Class;\n");
|
||||
\fwrite($handle, "use Amp\\ByteStream\\WritableStream;\n");
|
||||
\fwrite($handle, "use Amp\\ByteStream\\ReadableStream;\n");
|
||||
\fwrite($handle, "use Amp\\ByteStream\\Pipe;\n");
|
||||
\fwrite($handle, "use Amp\\Cancellation;\n");
|
||||
\fwrite($handle, "use Amp\\Http\\Server\\Request as ServerRequest;\n");
|
||||
\fwrite($handle, "use danog\\MadelineProto\\Broadcast\\Action;\n");
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
namespace danog\MadelineProto\EventHandler;
|
||||
|
||||
use Amp\ByteStream\ReadableStream;
|
||||
use danog\MadelineProto\Ipc\IpcCapable;
|
||||
use danog\MadelineProto\MTProto;
|
||||
use JsonSerializable;
|
||||
@ -107,4 +108,13 @@ abstract class Media extends IpcCapable implements JsonSerializable
|
||||
$v['_'] = static::class;
|
||||
return $v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a readable amp stream with the file contents.
|
||||
*
|
||||
*/
|
||||
public function getStream(): ReadableStream
|
||||
{
|
||||
return $this->getClient()->downloadToReturnedStream($this);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
use __PHP_Incomplete_Class;
|
||||
use Amp\ByteStream\Pipe;
|
||||
use Amp\ByteStream\ReadableStream;
|
||||
use Amp\ByteStream\WritableStream;
|
||||
use Amp\Cancellation;
|
||||
@ -1015,6 +1016,14 @@ abstract class InternalDoc
|
||||
{
|
||||
return $this->wrapper->getAPI()->getSponsoredMessages($peer);
|
||||
}
|
||||
/**
|
||||
* Obtains a pipe that can be used to upload a file from a stream.
|
||||
*
|
||||
*/
|
||||
public static function getStreamPipe(): \Amp\ByteStream\Pipe
|
||||
{
|
||||
return \danog\MadelineProto\Tools::getStreamPipe();
|
||||
}
|
||||
/**
|
||||
* Get TL serializer.
|
||||
*/
|
||||
|
@ -82,6 +82,8 @@ use function time;
|
||||
/**
|
||||
* Manages all of the mtproto stuff.
|
||||
*
|
||||
* @psalm-suppress PropertyNotSetInConstructor
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
final class MTProto implements TLCallback, LoggerGetter
|
||||
|
@ -159,7 +159,7 @@ trait Files
|
||||
};
|
||||
}
|
||||
$totalSize = 0;
|
||||
$callable = static function (int $part_num) use (&$totalSize, $size, $file_id, &$part_total_num, $part_size, $callable, $ige) {
|
||||
$callable = static function (int $part_num) use (&$totalSize, $size, $file_id, &$part_total_num, $part_size, $callable, $ige): array {
|
||||
static $offset = 0;
|
||||
$oldOffset = $offset;
|
||||
$offset += $part_size;
|
||||
|
@ -526,7 +526,9 @@ final class Ogg
|
||||
};
|
||||
$proc = Process::start(['ffmpeg', '-hide_banner', '-loglevel', 'warning', '-i', $inFile, '-map', '0:a','-ar', '48000', '-f', 'wav', '-y', '/dev/stdout'], cancellation: $cancellation);
|
||||
if ($in instanceof ReadableStream) {
|
||||
async(pipe(...), $in, $proc->getStdin(), $cancellation)->ignore();
|
||||
async(pipe(...), $in, $proc->getStdin(), $cancellation)
|
||||
->ignore()
|
||||
->finally($proc->getStdin()->close(...));
|
||||
}
|
||||
async(pipe(...), $proc->getStderr(), getStderr(), $cancellation)->ignore();
|
||||
self::convertWav($proc->getStdout(), $oggOut, $cancellation);
|
||||
|
@ -20,6 +20,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace danog\MadelineProto;
|
||||
|
||||
use Amp\ByteStream\Pipe;
|
||||
use Amp\ByteStream\ReadableBuffer;
|
||||
use Amp\ByteStream\ReadableStream;
|
||||
use Amp\Cancellation;
|
||||
@ -604,6 +605,14 @@ abstract class Tools extends AsyncTools
|
||||
return openFile($path, "a");
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a pipe that can be used to upload a file from a stream.
|
||||
*
|
||||
*/
|
||||
public static function getStreamPipe(): Pipe
|
||||
{
|
||||
return new Pipe(512*1024);
|
||||
}
|
||||
/**
|
||||
* Provide a buffered reader for a file, URL or amp stream.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user