Remux contents of multiple files to .mkv using batch - windows

I have a number of video files from TV shows and I want to add subtitles subtitles to each of them. While I can use MKV merge for a few files, but here the number of files is too much, and doing each one individually would take a lot of time.
I used the following:
for %x in (*.mp4) do mkvmerge "%x" -o "%~nx.mkv"
But it will only mux mp4 to mkv, and not add the subtitles(srt). My video files and subtitles have the same name for each episode. Thank you!

try this:
for %x in (*.mp4) do mkvmerge -o "%~nx.mkv" "%~x" "%~nx.srt"
For more info look at the docu.

Related

ffmpeg convert images with name pattern into video [duplicate]

I am trying to make an FFMPEG script that relied on a glob input pattern from Linux to Windows. Unfortunately that is not supported so I am looking for an alternative. I do not want to have to rename or copy the files every time I run the script because the files are used elsewhere and I cannot rename them and I would like to avoid duplication or unnecessary temporary files.
Are globs numerically sequential named images my only option here? Ideally I would like to input a list of image paths to FFMPEG as a substitute for ffmpeg -i *.jpg
The workarounds are to prepare a text file with the names and use the concat demuxer.
Or you can use image2pipe
cat *.jpg | ffmpeg -f image2pipe -framerate 25 -i - out.mp4
The best solution I could find (that's Windows compatible) was to generate a line separated list of files in a text file and pass that through to FFMPEG. For example, to generate a stabilized MP4 from a bunch of JPEGs:
ffmpeg -f concat -safe 0 -i ./files.txt -vf deshake=rx=64:ry=64 ./stabilized.mp4
Where files.txt is a list of the files in the following format. The safe option toggles the ability to have absolute/relative file paths.
# this is a comment
file 'C:/path/to/file1.jpg'
file 'C:/path/to/file2.jpg'
file 'C:/path/to/file3.jpg'

Input parameters to FFMPEG

I am trying to make an FFMPEG script that relied on a glob input pattern from Linux to Windows. Unfortunately that is not supported so I am looking for an alternative. I do not want to have to rename or copy the files every time I run the script because the files are used elsewhere and I cannot rename them and I would like to avoid duplication or unnecessary temporary files.
Are globs numerically sequential named images my only option here? Ideally I would like to input a list of image paths to FFMPEG as a substitute for ffmpeg -i *.jpg
The workarounds are to prepare a text file with the names and use the concat demuxer.
Or you can use image2pipe
cat *.jpg | ffmpeg -f image2pipe -framerate 25 -i - out.mp4
The best solution I could find (that's Windows compatible) was to generate a line separated list of files in a text file and pass that through to FFMPEG. For example, to generate a stabilized MP4 from a bunch of JPEGs:
ffmpeg -f concat -safe 0 -i ./files.txt -vf deshake=rx=64:ry=64 ./stabilized.mp4
Where files.txt is a list of the files in the following format. The safe option toggles the ability to have absolute/relative file paths.
# this is a comment
file 'C:/path/to/file1.jpg'
file 'C:/path/to/file2.jpg'
file 'C:/path/to/file3.jpg'

Converting MP4 from input folder, moving them to new output, resizing with FFMPEG

I would like to know how to do the following :
There are 2 folders on my desktop. One is called input, the other output.
1 : Input folder contains a number of MP4 video files.
2 : I execute a .SH script (OSX) and all MP4 video files in the
folder will be resized to 2 other sizes for HLS.
3 : The original video in the folder, the highest version, will be
also moved to the output folder after the other 2 versions were
rescaled and created by FFMPEG in the output folder.
After this, we will use the Apple segmentation tool to segment all 3 versions, and automatically deleting the 3 MP4 video's left in the output folder.
I am not experienced with programming, hence I can use some help on this.
As far as I came with some code :
#!/bin/bash
Cd ~/username/Desktop/input
for name in *.mp4; do
ffmpeg -i "$name" -vf scale=854:480 "../output/${name%.*}_middle.mp4"
ffmpeg -i "$name" -vf scale=426:240 "../output/${name%.*}_low.mp4"
mv "$name" "../output/${name%.*}_high.mp4"
Thanks heaps in advance,
John

Convert image sequence to video using ffmpeg and list of files

I have a camera taking time-lapse shots every 2–3 seconds, and I keep a rolling record of a few days' worth. Because that's a lot of files, I keep them in subdirectories by day and hour:
images/
2015-05-02/
00/
2015-05-02-0000-02
2015-05-02-0000-05
2015-05-02-0000-07
01/
(etc.)
2015-05-03/
I'm writing a script to automatically upload a timelapse of the sunrise to YouTube each day. I can get the sunrise time from the web in advance, then go back after the sunrise and get a list of the files that were taken in that period using find:
touch -d "$SUNRISE_START" sunrise-start.txt
touch -d "$SUNRISE_END" sunrise-end.txt
find images/"$TODAY" -type f -anewer sunrise-start.txt ! -anewer sunrise-end.txt
Now I want to convert those files to a video with ffmpeg. Ideally I'd like to do this without making a copy of all the files (because we're talking ~3.5 GB per hour of images), and I'd prefer not to rename them to something like image000n.jpg because other users may want to access the images. Copying the images is my fallback.
But I'm getting stuck sending the results of find to ffmpeg. I understand that ffmpeg can expand wildcards internally, but I'm not sure that this is going to work where the files aren't all in one directory. I also see a few people using find's --exec option with ffmpeg to do batch conversions, but I'm not sure if this is going to work with image sequence input (as opposed to, say, converting 1000 images into 1000 single-frame videos).
Any ideas on how I can connect the two—or, failing that, a better way to get files in a date range across several subdirectories into ffmpeg as an image sequence?
Use the concat demuxer with a list of files. The list format is:
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
Basic ffmpeg usage:
`ffmpeg -f concat -i mylist.txt ... <output>`
Concatenate [FFmpeg wiki]
use pattern_type glob for this
ffmpeg -f image2 -r 25 -pattern_type glob -i '*.jpg' -an -c:v libx264 -r 25 timelapse.mp4
ffmpeg probably uses the same file name globbing facility as the shell, so all valid file name globbing patterns should work. Specifically in your case, a pattern of images/201?-??-??/??/201?-??-??-????-?? will expand to all files in question e.g.
ls -l images/201?-??-??/??/201?-??-??-????-??
ffmpeg ... 'images/201?-??-??/??/201?-??-??-????-??' ...
Note the quotes around the pattern in the ffmpeg invocation: you want to pass the pattern verbatim to ffmpeg to expand the pattern into file names, not have the shell do the expansion.

Static image and a folder of mp3's?

I want to create a bunch of videos consisting of an single image which is shown throughout the whole video but each video has a different audio file. I can do it manually with various tools but the problem is that I have a lot of audio files and I can't optimize the frame rate (more on that later) and it takes a lot of time to do it that way but ffmpeg offers everything I need but the problem is that I don't know how to batch process everything.
The basic code:
ffmpeg -i song-name.mp3 -loop 1 -i cover.jpg -r frame-rate -t song-length -acodec copy output.mp4
What I want to achieve:
Let's say that I have a folder which consists of several audio files: song-name-1.mp3, song-name-2.mp3, ..., song-name-n.mp3 and cover.jpg.
I need a batch file which takes the name of every mp3 file in a folder (a FOR loop I suppose) and processes it with the same command:
ffmpeg -i song-name.mp3 -loop 1 -i cover.jpg -r frame-rate -t song-length -acodec copy output.mp4
So the image is always the same for every video. The song length can be taken with the tool mp3info and the corresponding command:
mp3info.exe -p %S song-name.mp3
Since I only have one image throughout the whole video, the optimal frame rate would be the inverse of the video length which is 1/length (where length is a variable in seconds which we get from mp3info).
So the final code should look something like this:
ffmpeg -i song-name.mp3 -loop 1 -i cover.jpg -r 1/length -t length -acodec copy song-name.mp4
Where "song-name" is a variable which changes for every iteration of the FOR loop (i.e. for every audio file in the folder) and length is a variable whose value we get with the command:
mp3info.exe -p %S song-name.mp3
I found examples of a FOR loop to fetch all file names of all mp3's in a specific folder but I do not know how to integrate mp3info. I hope that somebody can help me and I have some knowledge of the C programming language if that can be used in any way.
Here's the edited simplified version without the VBS math.
The reason %%S is used is that % is a special batch character used for %environment% variables and in forINdo loops and to get a single one in a forINdo command it has to be doubled. Similarly echo %% will echo a single percent sign.
#echo off
for %%a in (*.mp3) do (
for /f "delims=" %%b in ('mp3info.exe -p %%S "%%a"') do (
ffmpeg -i "%%a" -loop 1 -i "cover.jpg" -r 1 -t %%b -acodec copy "%%~na.mp4"
)
)

Resources