1
0
mirror of https://github.com/danog/MadelineProto.git synced 2024-11-30 05:58:58 +01:00

Fix playing and converting VoIP audio from a stream

This commit is contained in:
Daniil Gentili 2023-08-19 17:33:47 +02:00
parent c37df506ad
commit 1d989eeabe
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
11 changed files with 45 additions and 59 deletions

View File

@ -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>

View File

@ -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)",

View File

@ -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'])) {

View File

@ -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>

View File

@ -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");

View File

@ -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);
}
}

View File

@ -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.
*/

View File

@ -82,6 +82,8 @@ use function time;
/**
* Manages all of the mtproto stuff.
*
* @psalm-suppress PropertyNotSetInConstructor
*
* @internal
*/
final class MTProto implements TLCallback, LoggerGetter

View File

@ -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;

View File

@ -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);

View File

@ -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.
*