У меня есть дюжина или больше mp3-файлов, которые мне нужно объединить в один mp3-файл. Все файлы имеют одинаковую скорость передачи данных (320 кбит / с) и частоту дискретизации (44,1 кГц), но все они имеют разную длительность.
Я изучил три метода конкатенации, рекомендованных для stackoverflow ( Как объединить два файла MP4 с помощью FFmpeg ). Один метод действительно работает, но при воспроизведении выходного файла я обнаруживаю заметные звуковые артефакты (слышимые глюки) в каждой точке соединения.
Мне сказали, что эта проблема вызвана тем, что входные файлы не имеют одинаковую продолжительность. Это кажется вероятным, поскольку я добился определенных успехов в объединении аудиофайлов с одинаковой скоростью передачи данных, частотой дискретизации и длительностью.
Я видел в Интернете несколько более сложных сценариев, которые в настоящее время находятся за пределами моего понимания. Одно из решений, к которому я был направлен, требовало довольно глубоких знаний Python!
Однако мое исследование также включало сайт по адресу audio-joiner.com - и это был единственный полностью успешный метод, который я нашел, для файлов с неидентичной продолжительностью. Этот сайт обработал некоторые из моих входных файлов, соединил несколько файлов в один, и полученный объединенный выходной файл не обнаружил каких-либо слышимых сбоев в соединениях.
Я изучил процесс, который использовался сайтом, в надежде получить представление о том, где я ошибался, но сценарий на сайте (который выглядит как javascript на основе ajax) слишком сложен для меня .
Поскольку процесс, казалось, занимал довольно много времени, я не был бы слишком удивлен, узнав, что входные mp3-файлы преобразуются в какой-то другой аудиоформат, объединяются, а затем конвертируются обратно в mp3 для вывода. Но если это так, это не остановит меня при использовании этого процесса.
Кто-нибудь знаком с используемым подходом и может сказать, можно ли его воспроизвести с помощью ffmpeg?
.
ДОБАВЛЕНО -
В источнике на соответствующей странице перечислено 7 сценариев:
https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js
https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js
https://static.123apps.com/js/socket.io.js
https://static.123apps.com/js/shared_0.js
https://static.123apps.com/js/shared_1.js
https://static.123apps.com/js/ajoiner.js
https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js
.
ДОБАВЛЕНО -
Кажется, это успешная (javascript) функция, но для меня не очевидно, почему она работает (слишком сложно для меня!). Кто-нибудь может подсказать, какой подход он использует? Например, транскодирует ли он mp3-файлы в промежуточный формат и объединяет промежуточные файлы?
function start_join(e){
l("start_join():"),l(e);
var t;
return(t=$.parseJSON(e)) && $("#ajoiner").ajoiner("set_params",t),!0
}
function cancel_join(e){
return l("cancel_join():"),l(e),!0
}
!function(o){
var t={
init:function(e){
var t=o(this),n=o.extend({lang:{cancel:"Cancel",download:"Download"}},e);
o(this).data("ajoiner",{o:n,tmp_i:1,pid:-1,params:{}});
t.data("ajoiner");
t.ajoiner("_connect"),o("body").bind("socket_connected",function(){t.ajoiner("_connect")})
},set_params:function(e){
var t=o(this).data("ajoiner");
isset(e)?(e.uid=Cookies.get("uid"),t.params=e,t.params.lang_id=lang_id,t.params.host=location.hostname,t.params.hostprotocol=location.protocol,l("socket emit join:"),l(t.params),socket.emit("join",t.params)):error("set_params: params not set")
},_connect:function(){
var t=o(this).data("ajoiner");
l("_connect"),socket.on("join",function(e){
"progress"==e.message_type?(t.tmp_i,t.tmp_i++,void 0!==getObj("theSWF")&&(getObj("theSWF").set_join_progress(parseInt(e.progress_value)),l("SWF.set_join_progress("+parseInt(e.progress_value)+")")),isset(e.pid)&&(t.pid=e.pid)):"final_result"==e.message_type?(void(e.tmp_i=0)!==getObj("theSWF")&&(getObj("theSWF").join_finished(o.stringifyJSON(e)),l("SWF.join_finished('"+o.stringifyJSON(e)+"')")),last_conv_result=e):"error"==e.message_type&&l(e.error_desc)
}
)},_cancel_convert:function(){
var e=o(this).data("ajoiner");
0<e.pid&&socket.emit("cancel_convert",{pid:e.pid})
}
};
o.fn.ajoiner=function(e){
return t[e]?t[e].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof e&&e?void o.error("Method "+e+" does not exist"):t.init.apply(this,arguments)
}
}
(jQuery),$(document).ready(function(){$("#ajoiner").ajoiner()});