I have over 1000 audio files, all of which end in a mouse click. I would like to remove the last half second from all of them. The audio files have different length (i.e. 15sec, 5 sec ...) But one thing in common with all of them is the last half second has a mouse click sound. How do I trim in bulk the ending of the mp3 files within a folder using windows 10 command line? I already have FFMPEG downloaded. Thank you!
This is two questions in one:
How to remove the last 0.5 seconds from inputs of arbitrary durations?
How to incorporate this into a Windows batch script?
I'll answer #1 because I'm not a Windows user. The batch scripting will be up to you.
Get duration using ffprobe:
ffprobe -v error -show_entries format=duration -of csv=p=0 input.mp3
Trim using ffmpeg:
ffmpeg -i input.mp3 -t <duration> -c copy output.mp3
Replace <duration> with the output from ffprobe minus 0.5 seconds.
How to incorporate this into a Windows batch script?
This should do:
FOR %%A IN (*.mp3) DO (
FOR /F %%B IN ('ffprobe.exe -v error -show_entries format^=duration -of csv^=p^=0 "%%~A" ^| xidel -s - -e ". - 0.5"') DO (
ffmpeg.exe -i "%%~A" -t %%B -c copy "%%~dpnA_trimmed.mp3"
)
)
First of all, doing floating point calculations in Batch is officially impossible and unofficially really hard to script. That's why I suggest to let Xidel do the math. It's first of all a command line tool to download and extract data from HTML/XML/JSON, but it can do A LOT more!
Loop over all mp3-files in the current directory.
The ffprobe command as suggested by llogan piped to Xidel to subtract the 0.5s. For example, 25.547755 now becomes 25.047755.
Don't forget to escape the necessary characters inside the for-loop! The = and | in this case.
The ffmpeg command as suggested by llogan, which opens "%%~A (the mp3-file), sets the duration to %%B and creates a new mp3-file (<filename>_trimmed.mp3).
This code assumes the mp3-files, ffprobe.exe, xidel.exe and ffmpeg.exe are all in the same directory.
Related
Is it possible to take the title metadata of input file, and just use that as the filename for the output file? I'm trying to encode a series of video files, and I'd like to automatically append the name of episodes to the filename, but I'm still very new to using ffmpeg and googling proved unsuccessful so far.
I'm trying to also write a batch script that'd encode the entire folder, and currently it looks like for %%a in ("*.mkv") do ffmpeg -i %%a -filter_complex "[0:v][0:s:1]overlay[subs];[subs]scale=960:720" -map 0:a:1 -acodec copy -sn test.mp4
What should i put in place of "test.mp4"?
So after being helped along by Ilogan, i managed to find an answer to what i want, even though it doesn't actually work properly yet, but i decided to write down here what i managed to find out so far, part for me, part for other poor souls.
So, following Ilogan's tip i managed to find out that ffprobe -v error -select_streams v:0 -show_entries stream_tags=title -of csv=p=0 "%%a" does indeed work and returns the metadata of title that's coded inside video stream.
Next was using that as a variable in a batchfile, which hs been answered several times, but I'll include it here as well:
You want to enclose the command in a for loop that has following look: FOR /F "delims=" %%g IN ('ffprobe -v error -select_streams v:0 -show_entries stream_tags^=title -of csv^=p^=0 "%%a"') do (SET title^=%%g) the important parts: some tutorials show "tokens=*" instead of "delims=" which might work, but i think delims will work better here. the most important part is that the command contains an equal sign, and you need to use a caret sign ^ to escape and have the command line properly parse those.
The remaining problem is that with my script looking currently like this:
for %%a in ("*.mkv") do (
FOR /F "tokens=*" %%g IN ('ffprobe -v error -select_streams v:0 -show_entries stream_tags^=title -of csv^=p^=0 "%%a"') do (SET title=%%g)
ffmpeg -i "%%a" -filter_complex "[0:v][0:s:1]overlay[subs];[subs]scale=960:720" -map 0:a:1 -acodec copy -sn "%title%.mp4"))
it seems that windows is running the first occurrence of the command in the file, and by then the title variable is still empty - as a result I'm getting files with name ".mp4" and still figuring out how to handle that
EDIT: OK, so i found out that what you need to do, is put setlocal enabledelayedexpansion at the start, and the title variable needs to be in exclamation marks, not percent marks, and it works! I tested it, and it properly creates the files, with the titles.
How do I write a .bat file in Windows 10 that changes the frame rate for multiple mp4 video clips in a folder? For example; change the frame rate from 50fps to 25fps (without re-encoding or dropping frames, so that footage is essentially slowed down.)
At the moment these are the commands I've tried using in two separate .bat text files. (I'd like to combine them but don't know how yet).
for %%A IN (*.mp4) DO ffmpeg -y -i "%%A" -c copy -f h264 "%%A.h264"
for %%A IN (*.h264) DO ffmpeg -y -r 25 -i "%%A" -c copy
"%%A_25.mp4"
Problem is these commands don't replace the file extension type, they append to the existing one, ie. '.mp4' becomes '.mp4.h264' then '.mp4.h264_25fps.mp4', and I can't get the second one to work for some reason.
Any advice appreciated. How do I replace the existing file extensions for a group of clips and combine commands into a single .bat?
I'm converting a couple thousand .wem files to .wav format. Since .wem is an obscure file format, I've decided to convert the files with SoX.
The SoX standard installation includes a batch file for use with mass converting raw files, which I've happily used. I've modified the example to remove the need to drag and drop files onto the batch file, using nested loops.
cd %~dp0
mkdir converted
for %%f in (*.wem) do FOR %%A IN (%*) DO sox -t raw -e signed-integer -b 16 -c 1 -r 44100 %%A "converted/%%~nA.wav"
pause
It creates a /converted directory just fine, and then proceeds to output the command, the directory, and then moves on to (supposedly) the next file. Unfortunately, opening the /converted directory reveals that nothing was generated at all, and the conversion took a lot less time than it should have. I've tested it with .wem files prior, and it converts just fine, so I don't think it has anything to do with the format. More likely, it just has something to do with my amateur batch file programming. Any ideas?
Solved, thanks to Mofi.
Finished code:
cd %~dp0
mkdir converted
for %%I in (*.wem) do sox -t raw -e signed-integer -b 16 -c 1 -r 44100 "%%I" "converted\%%~nI.wav"
pause
Seems I really could do it in one loop.
I have videos in a folder of .h264 format and i want to convert them to mp4. now by default i can use ffmpeg to do this:
Here is the command:
ffmpeg -i youtube.flv -c:v libx264 filename.mp4
But, new h264 files are being added and I want to keep converting the videos so as to use it for my python script.
I know i can use this to initialize the variable
SET /A num=1
But how do i write a batch script to take all the videos from the directory one by one even though there new videos being added?
I wrote this but this isn't working:
#echo off
SET /A num=1
for file in E:\Records\1\*.h264
do
ffmpeg -i "$file" -c:v libx264 E:\Recods\1\converted\%num%.mp4
move E:\Records\1\"$file" E:\Records\1\done\
set /A num=%num%+1
done
PAUSE
I am making a done folder and moving the videos that have been converted there and in converted folder i am putting converted videos.. Now i just have to run a task scheduler each hour so that if there is a new entry it should convert it and move it to appropriate folder.
You can loop over all files (even with applying a filter) in a folder using the for loop in batch like this:
#echo off
setlocal EnableDelayedExpansion
set /a vid=0
cd /d "your_Folder\Goes here"
for %%f in (*.h264) do (
ffmpeg -i "%%~f" -c:v libx264 "!vid!.mp4"
set /a vid=!vid!+1
)
So what happens here?
The first line is used to have the program running in the correct directory.
After that all files ending with .h264 (might be a different ending in your case; just took it from the question) in that directory are processed using your command. For that the filepath is placed in the spot for the input file and the counter together with .mp4 is placed as the outputfile.
The counter is a bit more tricky because of how sets of parenthesis are evaluated in batch, which is as one whole block. As solution for this there are a lot of questions and answers on SO. Look for "Delayed Expansion batch" and you will find something like this answer.
Placing this as a Task-Scheduler-Task running on a regular basis should keep your folder updated. For actually monitoring the folder I found this impressive code that can be used in combination with the Task-Scheduler to run that on startup. If the monitoring triggers, you can execute the batch-file above and it should be run each time a file is added. You can adjust the powershell-file with file-filters as well to make it fit your needs.
What we have:
test.mp3
test.mp4
We want to merge this using ffmpeg
ffmpeg -i "test.mp3" -i "test.mp4" -c copy D:\test_final.mp4
The thing is we just need this to do for tons of videos.
What we currently have:
for %%a in ("merge\*.*") do ffmpeg -i "%%a" -i "%%a" -c copy D:\%%~na
So, what's the correct form? I have no idea :/
In merge there are always mp3 and mp4 files with the same name.
What you have looks pretty darn good, and you didn't describe exactly how it does not work for you.
To match your desired line more exactly:
Get only *.mp3 files
Use %%~pa%%~na to get the path and filename-only, but no extension, then add a .mp4 on the end of it.
Add a _final to the resulting name
If this isn't working for you, please describe exactly how it fails.
for %%a in ("merge\*.mp3") do (
ffmpeg -i "%%a" -i "%%~pa%%~na.mp4" -c copy D:\%%~na_final.mp4 )