Ed999
Ed999

Reputation: 3081

Can ffmpeg concatenate mp3 files using the process at audio-joiner.com?

I have a dozen or more mp3 audio files, which I need to concatenate into a single mp3 file. The files all have the same bitrate (320 kbps) and sample rate (44.1 kHz), but all of them have differing durations.

I have studied the three methods of concatenation recommended on stackoverflow (How to concatenate two MP4 files using FFmpeg). One method actually works, but when I play back the output file I find that there are noticeable audio artifacts (audible glitches) at each join point.

I've been told that this problem is caused by the input files not having identical duration. This seems likely, because I've had some successes in concatenating audio files with identical bit rate, sample rate, and duration.

I have seen, online, some much more complex scripts which are, at present, miles beyond my understanding. One solution I was directed to required a fairly deep knowledge of Python!

However, my research also included a site at audio-joiner.com - and this had the only completely successful method I've yet found, for files of non-identical duration. That site processed some of my input files, joined the multiple files into one, and the concatenated output file it produced did not have any audible glitches at the joins.

I looked into the process the site was using, hoping to get a clue as to where I've been going wrong, but the script on the site (which looks like ajax-based javascript) is too complex for me to follow.

Because the process seemed to take quite a long time, I wouldn't be too surprised to learn that the mp3 input files are being converted to some other audio format, joined, then converted back to mp3 for the output. But if so, that wouldn't put me off using the process.

Is anyone familiar with the approach being used, and can say whether it might be reproducible using ffmpeg?

.

ADDED -

There are 7 scripts, in all, listed in the source of the relevant page:

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

.

ADDED -

The successful (javascript) function seems to be this, but it isn't obvious to me why it is succeeding (too complex for me!). Can anyone suggest what approach it is taking? For example, is it transcoding the mp3 files to an intermediate format, and concatenating the intermediate files?

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

Upvotes: 0

Views: 1224

Answers (1)

the_RR
the_RR

Reputation: 392

Above there is a tiny python script to do such thing with ffmpeg.
The script was configured to run in the same folder of yours mp3, but you can adapt.

import os

def main():

    # ::.inputs
    extensions = '.mp3'
    path_folder_input = '.'
    path_file_output = 'set_joined.mp3'

    # ::. Make a path_file list
    list_files = []
    for root, dirs, files in os.walk(path_folder_input):
        for file in files:
            if file.endswith(extensions):
                print(file)
                list_files.append(os.path.join(root, file))

    # ::. Make a ffmpeg command
    index_final = len(list_files)-1
    stringa = "ffmpeg -i \"concat:"
    for index, path_file in enumerate(list_files):
        stringa += path_file
        if index != index_final:
            stringa += "|"
        else:
            stringa += f"\" -acodec copy " + \
                       f"{path_file_output}"

    # ::. Start join
    os.system(stringa)


main()

Upvotes: 1

Related Questions