Command: JoinMP3

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).

It does show as type is Standard.
I think it needs to be changed to scripting, but the the comments are wrong styled.
maybe @fred can actually copy/paste his button

I see there is a line "@script VBScript", remove that and try again. It should not be there.

1 Like

Thanks! That fixed it!

I've edited Fred's post above to clarify that it should be pasted into a Standard Function button, not a Script Function button.

Pasting into the wrong button type will be where the extra @script jscript line came from; it was not in the original code.

I've removed the duplicate copy of the code from the previous post to avoid confusion & save people wondering what the difference is. (At least, I think the two were the same code, just one in XML format and one not.)

I would think the button code is better, as it's more user friendly,
It has the names and tooltips already defined, a useful icon?, and easier to install
versus just the script contents.

Plus I had made some changes by removing the override on the EXE & PAUSE parameters of JoinMP3, that way the definition of the script takes precedence rather than the button, else the script won't work in other places than the button.

I recall pasting in a standard button only, but i could be wrong. Maybe i switched between the types when i saw the comment lines weren't getting highlighted in the standard button code, and that might have added the errant line of code.

It is slightly (although also harder to read), but not enough to offset the user-unfriendliness of having two near-identical versions of the same thing in one thread which people have to choose between, and where the original author cannot update one of them.

Any way to make the script work on folders of mp3s?
image

example above, convert a bunch of folders into mp3, by finding all mp3 files in them and converting to one mp3 with the folder name?

I saw in the script that it only expects files.

function Command_JoinMP3(data) {
	DOpus.Output("JoinMP3:");
	var files = GetFiles(data);
	if (!files || files.count==1){
		DOpus.Output("Not enough files given.");
		return false;
	}
	data.func.command.ClearFiles();
	data.func.command.SetType("msdos");


Function Getfiles only checks for files.

function GetFiles(data){
	if (data.func.args.got_arg.files)
		var files = data.func.args.files;
	else if (data.func.sourcetab.selected_files.count)
		var files = data.func.sourcetab.selected_files;
	else
		var files = data.func.sourcetab.files;
	return { enumerator:new Enumerator(files), count:files.count};
}

I am guessing we could create a loop and call JoinMP3 command in the button
OR
modify the script to accept both files & folders as input

Switching into flat view and selecting all mp3s from the subfolders could work as well.