Merge M4A files in Terminal - file

I have a couple of M4A (sound) files on a Mac that I want to combine into a single sound file. Can this be done with a Terminal command? Is there such a thing?

Yeah, ffmpeg doesn't work, contrary to what the internet echo chamber will tell you. At least not that way. It's incredible how many have to drool their wisdumb and waste everyone's time.
Here. Prove me wrong with a link, but this is what you want and this is the only place you'll see it. Tres simple.
ffmpeg -i file1.m4a -acodec copy file1.aac
ffmpeg -i file2.m4a -acodec copy file2.aac
cat file1.aac file2.aac >>filenew.aac
ffmpeg -i filenew.aac -acodec copy -bsf:a aac_adtstoasc filenew.m4a
I compiled my own ffmpeg for the extra libs, so I hope that that is one of the default ones. If not, it's definitely worth the hassle. I haven't been able to validate the above on a second system, but on my old Hardy Heron Ubuntu grunt system the joined file has all the right m4a meta data and tags and there is no change in audio quality.

FFMPEG can help you with this. Chekc out their How To Contatenate media files article.

github.com/mifi/lossless-cut is for audio/video editing using ffmpeg. Works fine for merging mp3/mp4/m4a with drag and drop.
sudo snap install losslesscut

Are you trying to have the audio playback one after another, or playback on top of one another at the same time?
Either way FFmpeg can do the trick. The way I read your question, you want them playing back at the same time... If that's the case, try:
ffmpeg -i [input1] -i [input2] -filter_complex "[0:a][1:a]amerge=inputs=2[a]" -map [a] -c:a libfdk_aac out.m4a
Note: this is going to compress the audio to AAC. It is one of the best audio encoders, so you won't really notice a difference, but if you need to maintain quality, you can always go uncompressed with pcm_s16le. However, I think you would then be better off going out to a .wav file.

Related

ffmpeg output Filename from multiple source

I want to have the output file to have same name from source ( for eg first filename from list.txt), how can I do it?
This is the code I have which converts the all the .avi in folder to a single files and renames it to output.avi.
Instead of output.avi I want the filename to be same as first filename from source folder or first filename from list.txt.
for %%f in (*.avi) do (
echo file %%f >> list.txt
)
ffmpeg -f concat -safe 0 -i list.txt -c copy output.avi
del list.txt
One more thing I want to know, is it possible to flip video horizontal or mirror it without re-encoding?
I don't think ffmpeg supports "backreferencing" the input filenames. I suggest handling that in bash or some through other means of scripting. E.g. you can use the first line of list.txt as the output filename like this (untested):
ffmpeg -f concat -i list.txt -c copy output/$(head -1 list.txt)
In this example if the first line is foo.avi, the output will be saved at output/foo.avi.
is it possible to flip video horizontal or mirror it without re-encoding
Apparently you can set rotation metadata without re-encoding to hint video players to play it back with the given rotation. Maybe there are metadata flags for mirroring or flipping, but I couldn't find any.
If this does not work for you, I don't believe there is a built-in solution to do this without re-encoding.
Is it possible to flip video horizontal or mirror it without re-encoding?
No, not when using filters (such as hflip, vflip, rotate, etc). Filtering requires re-encoding.
Rotation metadata as mentioned in another answer may suffice this use case, but support among players is not universal. There is no metadata for mirroring or flipping: only rotation.
If that is not acceptable then the player itself may have mirroring/flipping capabilities. Example:
mpv -vf hflip video.mp4

Automating FFmpeg/ multi-core support

I need help with FFmpeg/batch. I have a couple of large batches of images (+14000 files each batch, +5 MB each image, .TIFF all of them) and I'm stringing them together into a .mp4 video using FFmpeg.
The date in the metadata is broken because of the way they're stored upon creation, so the time and date (T/D) are on the file_name. I need each frame to have its respective T/D (so its File_Name) burnt onto them for accurate measurements (scientific purpose).
With the help of google and reddit, I've managed to semi-automate it like so:
Master.bat:
forfiles /p "D:\InputPath" /m "*.TIFF" /S /C "cmd /c C:\SlavePath\slave.bat #file #fname"
Slave.bat:
ffmpeg -i "%~1" -vf "drawtext=text=%~2: fontcolor=white: fontsize=30: fontfile='C\:\\FontPath\\OpenSans-Regular.ttf'" "D:\OutputPath\mod_%~1"
Running Master.bat will output each individual image with the text burnt onto them and change the File_Name to mod_'File_name'.TIFF
Real example: 2018-06-05--16-00-01.0034.TIFF turns into mod_2018-06-05--16-00-01.0034.TIFF
The problem is that FFmpeg doesn't like it when my files have "--" in them ("date--time.miliseconds.TIFF") and doesn't like the miliseconds either, so I have to change the name of all files "manually" using Bulk Rename Utility (BRU). So, using BRU I rename all files to 00001.TIFF, 00002.TIFF, etc. and FFmpeg likes me again. It works great, but it means I can't be AFK.
After that, I have to go back to cmd and manually start the image to video conversion.
Also, FFmpeg doesn't seem to be using all cores.
I need help finding a way to:
Change master.bat's output to 00001.TIFF etc. automatically in order of processing (i.e. first to be processed is 1.TIFF, 2nd is 2.TIFF)
Add ffmpeg's img-to-vid function to the automating system
Get my CPU to use all the cores effectively if possible. 2014/15 posts found on google make it seem as though FFmpeg doesn't support multi-core or hyperthreading.
64bit Windows, i7 7700hq, gtx 1050 4Gb, C: SSD, D: HDD
Try this:
ffmpeg -i "2018-06-05--16-00-01.%4d.TIFF" -threads 4 out.mp4
https://en.wikibooks.org/wiki/FFMPEG_An_Intermediate_Guide/image_sequence

Batch script to convert, youtube-dl webm file to mp3 with ffmpeg

I'm using youtube-dl to extract the best possible audio quality from youtube videos. However the best quality audio usually turns out to be the webm format, which isn't useful. I would like to write a batch script that converts the webm file to an mp3 with ffmpeg. I've already tried using this guide on reddit to do it, but it doesn't seem to work. It appears to create an empty mp3 file that displays an error when i try to play it and the meta data is also completly blank.
Here is the batch script:
for %%a in ("Downloaded\*.*") do %CD%\ffmpeg\bin\ffmpeg.exe -i "%%a" -vn -ar 44100 -ac 2 -ab 192k -f mp3 "Converted\%%~na.mp3" pause
I'll also give an explanation of how the whole thing should work.
The idea is, is that you use youtube-dl to extract the best possible audio, then put that file into the Downloaded folder (see pic below) and then you run the mp3 script (which uses commands from ffmpeg) to convert the webm file in the Downloaded folder to a mp3 file, and place it in the Converted folder. The mp3 script is the code above. But it doesn't seem to work properly.
I'm not very familiar with batch scripting, nor with ffmpeg so any help would be appreicated.
Here is the picture to complement the explanation part.
youtube-dl already contains this functionality - just specify that you want mp3:
youtube-dl -x --audio-format mp3 https://www.youtube.com/watch?v=BaW_jenozKc
Replace https://www.youtube.com/watch?v=BaW_jenozKc with your actual URL.
You can convert through this script:
for FILE in *.webm; do
echo -e "Processing video '\e[32m$FILE\e[0m'";
ffmpeg -i "${FILE}" -vn -ab 128k -ar 44100 -y "${FILE%.webm}.mp3";
done;
Save it into a .sh file and execute it. It will automatically convert all the .webm into .mp3
webm either uses vorbis or opus audio codec, both are far superior to mp3 in quality.
aac audio is available on youtube, which is somewhere between opus and vorbis in quality and is heavily supported by media players and gadgets.
quality wise, re-encoding lossy audio to another lossy audio is not recommended, especially if one of those autio formats is mp3.
i'd grab that aac if i were you.
as per this answer:
youtube-dl -f bestaudio[ext=m4a] --embed-thumbnail --add-metadata <Video-URL>
in my use case, .ogg was supported
ffmpeg -i "input.webm" -vn -c:a copy "output.ogg"
without reencoding: -c:a copy
.webm files indeed can contain vorbis audio, but it can also contain opus audio. Also an ogg file can contain both audio formats. One can transfer the audio without conversion to an .ogg file:
https://askubuntu.com/questions/1258842/how-to-save-the-audio-from-webm-to-ogg-without-transcoding-using-ffmpeg#1258910
If you added -f bestaudio option to the command
youtube-dl -x --audio-format mp3 https://www.youtube.com/watch?v=BaW_jenozKc ,
it would first download the best audio from youtube, and then convert it to mp3 without needing an ffmpeg bash script.
In this case the command would be
youtube-dl -f bestaudio -x --audio-format mp3 https://www.youtube.com/watch?v=BaW_jenozKc
Hope this helps.

Using only ffmpeg, is it possible to consume a source GIF image and output a video that is a set length > one loop through the input GIF?

Let's say I have an 8 frame animated GIF that is 2 seconds long. I would like to build a video file (codec not important at this point) that is 30 seconds long that consists of the source GIF repeating over and over.
Is it possible to do this using only ffmpeg? Answers that use convert or some other pre-processing utility do not count [The reason being that I would like to use this on PandaStream, which does not have that utility]. Let's also assume that shell scripts are out of the question as well, though it can be multiple ffmpeg commands.
Things I have tried that did not work (though maybe I did them wrong, I'm not terribly familiar with ffmpeg):
Using the -loop_input, -loop_output options present in the ffmpeg docs. Using both ffmpeg 1.2 and 2.0, I get a Unrecognized option 'loop_[input|output]' error message. I might be using this wrong though since the error is about not recognizing the option, though the docs say it is deprecated.
-loop option. Does not seem to do anything with GIF -> Video. I think this flag and the above flag are related to generating animated GIFs as the output.
Concat. Doing something like:
ffmpeg -i "concat:image.gif|image.gif|image1.gif|image2.gif|image3.gif|image4.gif" image-long.gif
Results in a 16 frame gif (so two gifs are concatenated) which is progress, though the output gif is of much lower quality.
I'm a bit at my wits end here (I have tried many other permutations of the above concepts), I'm at the point now of 'poking it with a stick', hopefully someone out there has done this!
Is it possible? Yes.
Looking at How to concatenate (join, merge) media files, we can take the gif and transcode to mpeg streams (you could copy the first one twice):
ffmpeg -i image.gif -f mpegts image1.ts
ffmpeg -i image.gif -f mpegts image2.ts
ffmpeg -i image.gif -f mpegts image3.ts
then concatenate them, outputting as a gif
ffmpeg -i "concat:image1.ts|image2.ts|image3.ts" -pix_fmt rgb24 output.gif
Starting with an mp4 or similar seems to give better results; replace the first step with
ffmpeg -i image.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts image1.ts
and repeat for the other copies.
I create multiple copies of the same because if I try to concat: the same file multiple times (concat:image1.ts|image1.ts|image1.ts) it doesn't work.
Enjoy

Using ffmpeg convert a file from one format to another

I'm new to ffmpeg and I was trying to find out how to convert a audio or video file from one format to another. I don't want to use CLI, I just want to know if I can use ffmpeg as a library and call a function to convert a file from one format to another. I went through the documentation and found functions avcodec_encode_audio and avcodec_encode_video but its not clear how I can use this to convert. A tutorial or an example will be very helpful.
usually i do this by command line
ffmpeg -i input.mp4 -vcodec copy -acodec copy out.mkv
here i/p file is input.mp4 which will be converted into out.mkv with having same codec of all elementary stream
NOTE: upper command will only work when the input.mp4 's all codec will be supported by .mkv container.
and if you are not concern with codec then use
ffmpeg -i input.mp4 out.mkv
this will convert mp4 to mkv (if necessary it will also change codec of output format)

Resources