@kirigosh

Как ускорить конвертацию ogg в mp3 через ffmpeg?

Есть бот телеграме, которому отправляешь голосовое сообщение (формат oga), а он тебе в ответ отправляет mp3 файл. Я решил реализовать тоже самое: поставил на виртуалку ffmpeg, скормил боту голосовуху и получил mp3. Всё получилось, но меня смутила скорость выполнения скрипта. В моём случае скрипт выполнялся 3-4 секунды, а в случае с чужим ботом - меньше секунды (очень быстро, кажется, что где-то 300мс). Я связался с разработчиком того бота и он сказал, что бот написан на Python (у меня PHP) и самое главное, что выполнение конвертации сделано асинхронно, так как это была самая медленная часть скрипта. Я сделал замеры своего бота и получил такую картину:
(важный момент microtime был умножен на 1000, то есть 1860 - это 1.86 секунды)
Результат таймера
file_path - 312.7338886261
get link - 0.0030994415283203
ffmpeg - 1860.6932163239
send file - 916.67604446411
global - 3090.4860496521

у меня самый медленный момент - тоже конвертация файла.

Вопрос: возможно ли как-нибудь запустить ffmpeg асинхронно?

Скрипт бота

1. я не заморачивался с названием и просто брал текущую метку времени для его имени.
2. я закомментировал строки с замерами, чтобы не отвлекали
$tga = json_decode(file_get_contents('php://input'), true);
function tlgrm($method, $data, $client = 'получатель') {
	$data["parse_mode"] = "html";
	$data["chat_id"] = $client;
	$ch = curl_init("https://api.telegram.org/апи бота/$method");
	curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => 1,CURLOPT_CUSTOMREQUEST => "POST",CURLOPT_POSTFIELDS => $data]);
	$r = curl_exec($ch);
	curl_close($ch);
	return json_decode($r, true);
}

function tgfile($path) {
	return "https://api.telegram.org/file/апи бота/$path";
}
$time = time();
$sec = "Результат таймера\n";


// ПОЛУЧЕНИЕ #FILE_PATH
# $t = microtime(1);
$path = tlgrm('getFile',['file_id' => $tga['message']['voice']['file_id']]);
# $nt = (microtime(1) - $t)*1000;
# $sec.= "file_path - $nt\n";

// ПОЛУЧЕНИЕ ССЫЛКИ НА ФАЙЛ #GET LINK
# $t = microtime(1);
$link = tgfile($path['result']['file_path']);
# $nt = (microtime(1) - $t)*1000;
# $sec.= "get link - $nt\n";

// SHELL EXEC #FFMPEG
# $t = microtime(1);
shell_exec("sudo ffmpeg -i $link tmp/$time.mp3");
# $nt = (microtime(1) - $t)*1000;
# $sec.= "ffmpeg - $nt\n";

// ОТПРАВКА ФАЙЛА #SEND FILE
# $t = microtime(1);
$data['audio'] = "https://mywebsite.com/tmp/$time.mp3"; // telegram отказался принимать относительную ссылку 
tlgrm('sendAudio', $data);
# $nt = (microtime(1) - $t)*1000;
# $sec.= "send file - $nt\n";

// ОТПРАВКА ОТЧЁТА
$gt = (microtime(1) - $gt)*1000;
$sec.= "global - $gt";
tlgrm('sendMessage', $sec);


p.s. меня, если честно, смутил ответ программиста, когда он сказал, что дело в асинхронности. Потому что данное действие является линейным: получение файла, конвертация, отправка. Нельзя конвертировать файл до того, как ты его получил. Но скорее всего здесь дело в инициализации ffmpeg. Если бы он был уже "заряжен", то возможно скорость была бы выше.
  • Вопрос задан
  • 192 просмотра
Пригласить эксперта
Ответы на вопрос 1
@Kokoulin
Php senior developer
Скорее всего вы упираетесь в производительность сервера (у меня конвертация через ffmpeg достаточно бодро выполняется)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы