Command: JoinMP3

JoinMP3 - a script command to join mp3 or other music files with the help of ffmpeg.exe.

Commandline params (optional and overriding script-config defaults if those exist):

  • FFMPEGEXE (path to ffmpeg.exe)
  • FILES (separate files by blanks ( ), enclose in double quotes (") if filepath contains blanks)
  • TARGETFILE (if omitted a file "joined__joined." will be automatically created)
  • PAUSEATEND (=true/false)

Script config:


The command outputs some details in the script console, you may have a look there, if something does not work as expected.
Should work in flatview as well (not tested).

Installation:
To install the command, download the *.js.txt file below and drag it to Preferences / Toolbars / Scripts.
Edit the path to ffmpeg in the script-config and create a new button / menu entry which calls "JoinMP3".
Make sure you have only music files in your lister or only music files selected before running the command, if not ffmpeg will scream.

Have fun with it! o)
tb

Download:

1 Like

Thanks tbone, all working well so far (now that I have updated to 11.5) 11.4 was a no go.
Works in flat mode, regardless of whether the TARGETFILE arg is used or not, so that is good.

One question; what it the FILES arg for? I mean, what purpose does it serve?

Thanks for this by the way.
I'll report back if I manage to break it :stuck_out_tongue:

gah, nothing's ever simple is it?

Your script works fine so far, but there is a problem with the file it outputs. I am guessing that this is ffmpeg's fault. I will have a close look and see if I can figure out what is the cause of the problem.
FWIW this is what mp3val says about 2 files I just did...

Analyzing file "C:\Program Files\Serviio\lib\23mine.mp3"...
WARNING: "C:\Program Files\Serviio\lib\23mine.mp3" (offset 0x163838c): MPEG stream error, resynchronized successfully
WARNING: "C:\Program Files\Serviio\lib\23mine.mp3" (offset 0x1e6de2c): MPEG stream error, resynchronized successfully
INFO: "C:\Program Files\Serviio\lib\23mine.mp3": 159424 MPEG frames (MPEG 1 Layer III), +ID3v2, CBR
Done!

or

Analyzing file "C:\sb\9.mp3"...
WARNING: "C:\sb\9.mp3" (offset 0x2001a9): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x391cc2): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x5be79b): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x74a544): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x8a7b7d): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x9c8386): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0xb9469f): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0xcf4d98): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0xe7fb01): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x110b46a): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x12d0013): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x14a230c): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x1611335): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x17e18ee): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x192b657): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x1a84780): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x1bcdcc9): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x1d3d442): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3" (offset 0x1e8698b): MPEG stream error, resynchronized successfully
WARNING: "C:\sb\9.mp3": Wrong number of MPEG frames specified in Xing header (160942 instead of 160962)
WARNING: "C:\sb\9.mp3": Wrong number of MPEG data bytes specified in Xing header (33476144 instead of 33480096)
INFO: "C:\sb\9.mp3": 160962 MPEG frames (MPEG 1 Layer III), +ID3v2, CBR
Done!

Yes, what's written in the console window is all ffmpeg.exe and out of my hands. It just seems to niggle on your files, it did that for some of mine too.

Quite every file/folder related command of DO, has some paramters to make it operate without a selection or lister.
So you can run "JoinMP3" from outside with dopusrt.exe for example. It can also be handy to combine your current selection of files with a static file, which you would always like to be the last in your joined file e.g. You'd call JoinMP3 similar to this then:

JoinMP3 TARGETFILE="foo.mp3" FILES={allfilepath$} "C:\tmp\outtro.mp3" 

Give your best! o))

[quote]Quite every file/folder related command of DO, has some paramters to make it operate without a selection or lister.
So you can run "JoinMP3" from outside with dopusrt.exe for example. It can also be handy to combine your current selection of files with a static file, which you would always like to be the last in your joined file e.g. You'd call JoinMP3 similar to this then:[/quote]

Ah, I see, I did not realise this, but I do now.

The annoying thing here is that after all this effort, on your part mainly, but also on others, the damn thing doesn't work, well, it works in that it joins the files, but it doesn't work in producing a 'clean' mp3. I guess I could add something that fixes the brokenness after the join is complete, but I can't help but think I am flogging a dead horse.

As I said elsewhere, using ffmpeg was not the object of the exercise, it was simply to use Opus to call a command line app to produce a clean mp3 file, losslessly, from selected. I have looked and looked, but I just can't find anything that can do this. They are either GUIs with no command line, or things that produce even more borked mp3s. I wouldn't have thought this was so hard, but...

MP3merge works flawlessly, but only via a GUI. It may have to be that I think. It seems kinda counter productive to create mp3s only to then need to 'fix' them.

I apologise for what may end up being a waste of your time. :frowning: One I owe ya. But in any case, thanks, I learned some stuff in this, so not all is lost.

If it can be broken, I will find a way :stuck_out_tongue:

ta

Actually, I take most of that back.

Because your script method is so fast, the additional few seconds needed to tidy up, makes it viable.
It was easy to set up a button to fix the files, and once I tried it, it is so quick and painless, that it is really a non-event. It's annoying that it needs to be done, but life wasn't meant to be easy!
Thanks tbone.

Could you please explain your last post to me again? I didn't get what you mean and what you exactly fixed because of .., to make things any better.

ffmpeg is iffy when it comes to joining the individual files. Sometimes it can produce a 'clean' joined mp3, sometimes not. The fault is ffmpeg itself, not Opus nor your script nor my button. I was saying that I am sorry that you went to so much efffort to make something work, when it turned out that the results were less than stellar, through no fault of your own. I planned to abandon the idea of ffmpeg and revert to the drag and drop to another program that I used to use, but thought it worth at least seeing how much effort it would be to run one more operation on the broken output files.

As it turns out, it is very little effort indeed to run another program after your script does the joining, to fix the anomalies in the output files. It is very fast and it's nice and clean, no torturous convoluted command line strictures to contend with.

So the result is, your script plus an additional button to tidy up, and we have success!

So I select JOIN, select JOIN, select JOIN, etc, then once that is done I press my button that selects all the joined files and fixes them.
Voila.

Ok got that now, thanks! o)

So now we are curious (at least I am..o), to know what your post-process fix-tool is and how you use that and what it actually fixes.
Clicking noises and stuff I guess? Must say, I did not join many mp3s while doing the command, but the ones I listened to after, were all quite ok, absolute nothing to complain. I'm very interested in getting this ready for use (with no anomalies in the resulting files of course), whenever I might need it myself.

It fixes frame errors and other things that I really don't understand what they are, or what they do. I can't even say for sure that the errors that it fixes would even be noticeable under normal conditions. I do know that in files that HAVE had isses with clicks and noise and other stuff, it was often the case that these (and other errors) were the cause, and that running them through mp3val fixed at least part of the problem. I doubt that it would fix the clicks, but as I said, it has fixed things before for me, I never worried too much about what or how, I was just happy to see a clean result.

In audiobookland, people just can't seem to leave the source files alone, and they use every cheap nasty piece of software on the planet to alter, join, split, chapterise, rejoin, resplit, reencode, and alter the original file, so that it often ends up a nightmarish mess that can cause havoc with some players.

Not sure if it is ok to post links here, so I won't, but the program I use is mp3val. It is free and has a command line version as well as a GUI.
If you join a series of files using your script, drag and drop them to mp3val and then hit SCAN FOR ERRORS (the magnifier) and you will see what I mean.
If you use another free tool, called mergemp3, on the same source files, and test the output, you will see that they all come out shiny clean. In other words, it ain't the files, it is the tool doing the joining that is the issue.

Anyway, the function is simple.

"C:\Program Files (x86)\MP3 Val\mp3val" {fs!} -f -nb pause

Super fast, -f does the fixing, the -nb arg does the cleanup, and the resulting files will pass muster.

Who knows, it all may be a waste of time, these frame and other errors may be a non-event? Still, I kinda like to see that OK status :slight_smile:

Ah ok! I know mp3val, I used it in the past as well, I think I had to deal with broken mp3-tags but cannot remember exactly.
Thanks for giving these details!

It picks up NO TAGS as "PROBLEM" which is kinda silly, but yeah, can fix screwed up tags amongst other things.

Anyway, my pleasure. Pity it was all so hard!

Bed.
zzzzzzzzzzzzzzzzzzzzzzzzzzzz

Yes man, what a mess all this mp3 stuff is over and over again. o) Just tried to find some references to ffmpeg, error while joining and mp3val and came up with a handful of different ways of doing a mp3-join. And you mentioned it, there seems to be no perfect way of doing it (in a single tool on command line at least). Your approach with ffmpeg and mp3val seems to be one of the easiest and best ways to do it, so that shall be fine. You should be good after mp3val did it's thing, it seems to me, it is expected of ffmpeg to create files with slighty incorrect streams, which mp3val.exe should fix up nicely.

In case you'd like to mess around some more, here's a link describing things using a completly different set of commands.. o):
practicatechnical.com/comput ... -mp3-files

Btw, did you look for mp3 tags and what they look like after the join with ffmpeg? Cover information? V1 and V2 tags still there etc.? I did not yet.

PREPOST-EDIT:
Watch the link, especially that line somewhere saying: id3cp 1.mp3 all.mp3 that tool should copy those tags over to the joined file.

I have seen that page as it happens, I reckon I have seen every page on the net about this. Unfortunately, it is mostly a non-event. mp3wrap writes all sorts of stuff that shouldn't be there into the joined file, so that it can be 'unwrapped' later. If I wanted to do that, I would just use Winrar to combine them, because the result is effectively the same. mp3wrap was one of the many tools I tried :frowning:

As for the tags via your method, no good, they get lost in translation, but in my case, there are no tags, because I just ripped the tracks, so that isn't an issue. The cover survives though for some reason, go figure.

From memory there was a way to retain the tags using ffmpeg, but because this was a non-event to me, I didn't bother even trying. I think trying to keep exisiting tags intact, may be further complicating what is already a complicated enough issue and since adding tags (in my case anyway) is simple, (using mp3bookhelper) I am not too worried. That example you gave uses mp3wrap, so that point alone makes it a no go for me.

I don't get though why ffmpeg is expected to make mistakes, when it is clearly possible to do it properly, since mp3merge produces perfect results. If only mp3 merge took command line args, none of this would be needed. I seem to recall the author of mp3merge saying that he wrote the program because there were no programs out there that worked! hehe, I should have listened to him.

Oh well, we shoud be thankful that we can actually do the job without too much effort, well, now that all the effort has been done :slight_smile: ta again

Thanks for the script.

Here is a sample button, the one I use:

(When pasting into the Button Editor, ensure the Function drop-down is set to Standard Function (Opus or External). Do not set it to Script Function for this command.)

@disablenosel
@filesonly
@nodeselect
@runmode:min
@nofilenamequoting

// ===============================================
// Secure step: if you have selected some files that are not mp3 this will deselect them and prevent errors from ffmpeg
// (This requires you have a proper filter set)

Select "NOT mp3" FILTER DESELECT 

// ===============================================
// This will prompt you for the name of the new mp3

@runonce:@set target={dlgstringS|New MP3 file name:|{file$|noext}}

// ===============================================
// Here you can customize the ffmpeg path (it handles alias)

@set exe=/Programs\Multimedia\ffmpeg\bin\ffmpeg.exe

// ===============================================
// Here is the final command
// Just customize it for your need
JoinMP3 TARGETFILE "{sourcepath}{$target}.mp3" PAUSEATEND false FFMPEGEXE "{$exe}"

Here is the "NOT mp3" filter used in command

Create a new filter and name it NOT mp3

add 1st rule such as: type | match | file only
add 2d rule such as: name | match | ~(*.mp3) | tick Use wildcards | untick Use regular expression

It's wise to check the mp3 produced by ffmpeg for errors and fix them. Just follow this step requiring only one click.

Install mp3val.

Use this button:

@disablenosel
@filesonly
@nodeselect

// ===============================================
// Secure step: if you have selected some files that are not mp3 this will deselect them and prevent errors from mp3val
// (This requires you have a proper filter set)

Select "NOT mp3" FILTER DESELECT

// ===============================================
// Here you can customize the mp3val path (it handles alias)

@set exe=/Programmes\Multimedia\Mp3val\mp3val.exe

// ===============================================
// Left click action: run the fix mp3 command and generate a log file in the source path.
// If a fix is needed the original mp3 file is backup by mp3val.

@keydown:none

@sync:"{$exe}" {filepath} -f -l{filepath|..\}mp3Fix.log
notepad.exe {filepath|..\}mp3Fix.log

// ===========================================
//  Left click + SHIFT key action: Only analyze the mp3 files and generate a log file; no fix is attempted
@keydown:shift

@sync:"{$exe}" {filepath} -l{filepath|..\}mp3Fix.log
notepad.exe {filepath|..\}mp3Fix.log

//  ============= Command OPTIONS ==============
//  -l[logfile] = Log file name. If this argument is missing, all the information will be written to stdout. 
//  -f = réparation
//  -si = Suppress INFO messages. 
//  -nb = Delete .bak files that were created during file rebuilding. Use this option together with -f. 
//  -t = Keep file timestamps. Use this option together with -f. 

//

Good, thank you Fred! o)

Is there a way to install the dependencies in a portable way?
Can the script automatically download the dependencies to a fixed path in the appdata of dopus?
Can I put the exes in the Scripts folder?

image
I have defined the filter already

so I don't know why this wouldn't work

And for this one

The button works on each single file, rather than as a batch, so it is not as useful, and the prompt for notepad get's annoying if no log files is created. Can't you show the output of the logfile in the script output?

Seems your button is set to type "Scripting" and VBScript. For Freds button, the type of button should be the regular DO button (Standard, DO or external).