I would like to combine the two following commands to find mp4 files and convert them to mp3 and save them with same name.
The two command line:
find ./ -name '*.mp4'
ffmpeg -i video.mp4 -vn -acodec libmp3lame -ac 2 -ab 160k -ar 48000 audio.mp3
With find's -exec functionality:
find ./ -name '*.mp4' -exec bash -c 'ffmpeg -i $0 -vn -acodec libmp3lame -ac 2 \
-ab 160k -ar 48000 ${0/mp4/mp3}' {} \;
This should make xyz.mp4 to xyz.mp3.
Related
Im using ffmpeg to compress footage and i want to compess the footage of a specific day but when i overwrite the files it outputs a empty stream because it writes as it reads at the same time so i want to rename the output file. Find will give the full path which is necessary but i don't know how to change the actual file name, rather than the path.
Any suggestions?
find /home/server/recordings/compress -name '*.mp4' -print0 | xargs -0 -I{} ffmpeg -i {} -c:v libx265 -preset fast -crf 25 -x265-params "vbv-maxrate=1500:vbv-bufsize=1000" -c:a aac {}
The last argument in ffmpeg is the output filename. So you can change your command to
find /home/server/recordings/compress -name '*.mp4' -print0 | xargs -0 -I{} ffmpeg -i {} -c:v libx265 -preset fast -crf 25 -x265-params "vbv-maxrate=1500:vbv-bufsize=1000" -c:a aac {}.out
This way all the output files will have .out appended.
Pass file names to sh using -exec and modify the filename there. For example:
find /home/server/recordings/compress -name '*.mp4' -exec sh -c '
ffmpeg -i "$1" -c:v libx265 -preset fast -crf 25 -x265-params "vbv-maxrate=1500:vbv-bufsize=1000" -c:a aac \
"${1%/*}/modified_${1##*/}"
' _ {} \;
I'm trying to create a script to convert all .mp4 videos into subfolders.
My hierarchy is :
Folder_1/
Videos_encoded/
Videos_orig/
first-video.mp4
video_2/
video-in-folder-video_2.mp4
I want to compress all .mp4 (with into subfolders) are in the Videos-orig/ to the videos_encoded as the destination folder.
I tried :
find /home/user/Folder_1/videos_orig/ -type d | while read ligne
do
cd "$ligne"
for i in *.mp4;
do
ffmpeg -y -i "$i" -ar 44100 -c:v libx265 -b:v 1000 -c:a mp3 -b:a 128k /home/user/Folder_1/videos_encoded"$(basename "${i/.mp4}").mp4"
done
done
But I have the error message : **.mp4 no such file or directory* (result of ffmpeg command).
I don't understand ...
There is it a better way to perform this project ?
Thanks you very much in advance for your help :)
Regards
If not preserving the directory structure in the output is fine, I think this example would be sufficient by solely using find with -exec
find orig/ -type f -name "*.mp4" -exec sh -c 'ffmpeg -i "{}" "encoded/$(basename {})"' \;
The command works, but it doesn't compress all of my files.
My command line :
find /volume1/Master_1/Unites_communes/No_compressed/ -type f -name "*.mp*" -exec sh -c 'ffmpeg -n -i "{}" -crf 23 -ar 44100 -c:v libx264 -b:v 1000 -c:a mp3 -b:a 128k "/volume1/Master_1/Unites_communes/Cours_videos/$(basename {})"' \;
I run :
find /volume1/Master_1/Unites_communes/No_compressed/ -type f -name "*.mp4" -print
and I have :
Sortie standard/erreur :
/volume1/Master_1/Unites_communes/No_compressed/2017-10-13_131756.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-23_132120.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-24_090340.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-24_131336.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-25_085744.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-25_131357.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-26_133340.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-27_083836.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-27_133906.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-13_090642.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-10_125731.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-10_090037.mp4
/volume1/Master_1/Unites_communes/No_compressed/2017-10-04_140230.mp4
Total : 13 Files
In the destination I have only 7 files compressed and that it.
I have a problem in my ffmpeg command ?
I'm on a Synology, if it can help you.
I want this Script to run in a loop every hour. The main goal is to convert the wav files that I export to my VM share folder when using Ableton.
Messy Idea of what I want but need lots of help with
for file in /mnt/hgfs/VMshare/transfer/*
do
if ["$file" == "/mnt/hgfs/VMshare/transfer/*.wav]
then
find -name "*.wav" -exec ffmpeg -i {} -acodec libmp3lame -ab 128k {}.mp3 \;
else
echo "NO WAV TO CONVERT"
mv /mnt/hgfs/VMshare/transfer/*.mp3 /root/Desktop/MP3Music/
Change the FILE_PATH variable, destination path and ffmpeg command as per your need. This worked for me.
#!/bin/bash
FILE_PATH=/path/to/wav/format/files/*.wav
for FILE in `ls $FILE_PATH`
do
BASENAME=`basename $FILE`
ffmpeg -i $FILE -vn -ar 44100 -ac 2 -ab 192k -f mp3 `dirname "${FILE}"`/${BASENAME%.wav}.mp3 > /dev/null 2>&1
mv `dirname "${FILE}"`/${BASENAME%.wav}.mp3 /path/to/destination/
done
OR
Single command:
find /path/to/wav/files/ -name "*.wav" -type f | xargs -I {} ffmpeg -i {} -vn -ar 44100 -ac 2 -ab 192k -f mp3 {}.mp3
But the above stores the output files as *.wav.mp3, you may need to rename it while moving to destination path.
I have about 300 videos in .mp4 files that I need re-encode as new .mp4 files and to convert them to .webm and .ogg files.
I want to do it at the command line using ffmpeg, and I have the following command that converts the .mp4 into a .webm.
find ./ -name '*.mp4' -exec bash -c 'ffmpeg -i "$0" -vcodec libvpx -acodec libvorbis -cpu-used 5 -threads 8 "${0%%.mp4}.webm"' {} \;
Can someone help me modify this command to two separate commands, one for .mp4 -> .mp4 (suffixing the filename with -2) and another for .mp4 -> .ogg?
Thank you.
Well, as I didn't get any replies, I did find the answer myself.
So, for the benefit of others looking to do the same thing, here are the various commands I put together:
webm
find ./ -name '*.mp4' -exec bash -c 'ffmpeg -i "$0" -vcodec libvpx -acodec libvorbis -vf scale=-1:480 -cpu-used 5 -threads 8 "${0%%.mp4}.webm"' {} \;
ogv
find ./ -name '*.mp4' -exec bash -c 'ffmpeg -i "$0" -vcodec libtheora -acodec libvorbis -vf scale=-1:480 -cpu-used 5 -threads 8 "${0%%.mp4}.ogv"' {} \;
flv
find ./ -name '*.mp4' -exec bash -c 'ffmpeg -i "$0" -c:v libx264 -ar 22050 -crf 28 -vf scale=-1:480 -cpu-used 5 -threads 8 "${0%%.mp4}.flv"' {} \;
mp4
find ./ -name '*.mp4' -exec bash -c 'ffmpeg -i "$0" -vcodec libx264 -vf scale=-1:480 -cpu-used 5 -threads 8 "${0%%.mp4}-2.mp4"' {} \;
jpg
find ./ -name '*.mp4' -exec bash -c 'ffmpeg -i "$0" -ss 00:00:10 -vframes 1 -r 1 -vf scale=-1:480 -f image2 "${0%%.mp4}.jpg"' {} \;
Note that I have added the flag -vf scale=-1:480 which scales the video proportionately. I have set the height to 480px and the width is automatically calculated.
Also, note that I have also included a screenshot export from each video. The capture is made at the 10th second of the video and is saved as a jpeg file.
If you would like to retain the dates of the original files so that the new version (.webm, .ogv, .mp4, .flv) have the same modification dates, you can use the touch command as follows:
touch -r oldfile newfile
I want to convert three files with a single command. I used the following command:
-i "C:\fil1.mp4" -i "C:\file2.mp4" -i "C:\file3.mp4" -acodec libmp3lame -ab 32k -ar 22050 -ac 2 -b:v 128k -r 20 -s 176x144 -y file1.mp4 -acodec libmp3lame -ab 32k -ar 22050 -ac 2 -b:v 128k -r 20 -s 176x144 -y file2.mp4 -acodec libmp3lame -ab 32k -ar 22050 -ac 2 -b:v 128k -r 20 -s 176x144 -y file3.mp4
but it converts the first files with names fil1.mp4, fil2.mp4, fil3.mp4 but I want all files should be convert with its output file names.
Using -map helps with specifying which input goes with which output.
I used this code to convert multiple audio files:
ffmpeg -i infile1 -i infile2 -map 0 outfile1 -map 1 outfile2
also use -map_metadata to specify the metadata stream:
ffmpeg -i infile1 -i infile2 -map_metadata 0 -map 0 outfile1 -map_metadata 1 -map 1 outfile2
I wrote bash script for it.
You can modify as you want:
#!/bin/sh
BASE_DIR=$HOME/Videos/mov
OUTPUT_DIR=$BASE_DIR/avi
FILES=$(ls $BASE_DIR | grep .MOV)
for FILE in $FILES
do
FILENAME="${FILE:0:-4}"
ffmpeg -i $BASE_DIR/$FILE $OUTPUT_DIR/$FILENAME.avi
done
I have tried David Blum's script, there was a problem with spaces in filenames. Here's my modified script that uses basename to remove the file extension from filenames. It operates on the current directory, assuming a subdirectory called 'avi':
#!/bin/sh
OUTPUT_DIR=./avi
#IFS=$'\n' # split only on newlines
for FILE in *MOV
do
FILENAME=`basename "${FILE}" .MOV`
ffmpeg -i "$FILE" "$OUTPUT_DIR/$FILENAME.avi"
#echo $FILENAME
done
find ./ -name "*.wav" -exec ffmpeg -i {} -c:a libopus {}.opus \;
Maybe you could try using Different parallel outputs as in the FFMPEG documentation ?
When I have more files to work, I create a spreadsheet sheet and I do the command with "holes".
Every hole match to a file (filename).
I copy/paste in a file which become a script.
I know it is not perfect bet if it can help you.