Passing spaces conteined string to script - linux

I use such small script to convert videos from my SAT receiver to h264/mp3 format.
[maciek#piotr Pobrane]$ cat ./conv_sat_to_clean_ts
#!/bin/bash
ffmpeg -i $1.ts -movflags +faststart -vcodec h264 -acodec mp3 -f mpegts $1-new.ts
The problem is that when I call that script in such way:
./conv_sat_to_clean_ts ./Operacja\ Dunaj.ts
it shows me an error:
./Operacja: No such file or directory
So that means that spaces included in call parameters are ignored and filename is not interpreted correctly.
Is any way to resolve that problem?

Give $1 in double quotes since filename has space.
ffmpeg -i "$1".ts -movflags +faststart -vcodec h264 -acodec mp3 -f mpegts "$1"-new.ts
and run the script without .ts
./conv_sat_to_clean_ts ./Operacja\ Dunaj
or
./conv_sat_to_clean_ts "Operacja Dunaj"

Yes. RBH was right. Now my script looks like this and work properly.
#!/bin/bash
ffmpeg -i "$1" -movflags +faststart -vcodec h264 -acodec mp3 -f mpegts NEW-"$1"
And spaces in filenames (as script call parameter) are interpreted correctly

Related

ffmpeg split | merge video voice not sync

there are what i done:
download a full mp4 file.
due to it's watermark(0s-10s), i split the full video into 2 parts from 10second. the first part with watermark.
use ffmpeg delogo the first part.
merge the two video into a full again.
wget -O download.mp4
ffmpeg -i download.mp4 -vcodec copy -acodec copy -t 00:00:10 tmp1.mp4
ffmpeg -i download.mp4 -vcodec copy -acodec copy -ss 00:00:10 tmp2.mp4
ffmpeg -i tmp1.mp4 -vf "delogo=x=432:y=44:w=1060:h=108" -c:a copy tmp3.mp4
echo file tmp3.mp4 > mergelist.txt && echo file tmp2.mp4 >> mergelist.txt
ffmpeg -f concat -i mergelist.txt -c copy output.mp4
problem i faced:
in the last merged video, only one tmp part is fine, the other's video and voice not sync and play time more faster than before.
why i divide it, delogo(although only the first 10 seconds shows) full video more than 1h, re-encode takes much time, 10s part fine to me.
Have you tried this?
ffmpeg -i download.mp4 -vf "delogo=enable='lte(t,10)':x=432:y=44:w=1060:h=108" -c:a copy output.mp4
I'm assuming delogo filter is timeline editing enabled.

ffmpeg exported file is broken

I am using using ffmpeg to trim and join several audio files. The ouput audio file can be played as a normal file, but when I open it in some C# codes, exceptions are always throwing, says "MP3 Header is missing". I am new to ffmpeg and I googled for many times but seems no one is encountering this problem.
Here is my ffmpeg command to trim an audio file:
ffmpeg -i input_1.mp3 -ss 00:00:00.000 -to 00:00:01.000 -acodec libmp3lame 1.mp3
(The input audio format can be mp3/wma/wav/m4a/aac)
And the following is for joining all the audio files:
ffmpeg -safe 0 -f concat -i list.txt -acodec libmp3lame join.mp3
The list.txt contents:
file C:\\1.mp3
file C:\\2.mp3
file C:\\3.mp3
Problem soved! Thanks to Gyan's comment under my question.
The main point:
Make sure all converted files have same sampling rate and channel count i.e. add -ar 44100 -ac 2
The above parameters did solve my problem.

How to tell ffmpeg to loop through all files in directory in order

ffmpeg has concat option for this but all streams start working really bad and breaking sound after a day of streaming.
I tried looking at loops but i couldnt figure out how to execute a loop with ffmpeg command so it transcodes all files in 1 directory
/lely/ffmpeg -y -re -i /home/ftp/kid1.mp4 -vcodec copy -acodec copy -dts_delta_threshold 1000 -ar 44100 -ab 32k -f flv rtmp://10.0.0.17:1935/live/kid
In folder /home/ftp/ there are files kid1, kid2, kid3 - all *.mp4 files
So basically i would like a loop to change the input to next file every time previous ends.
Maybe you could use find and xargs to help you feed the files for ffmpeg:
find /home/ftp -name "*.mp4" | xargs -I $ /lely/ffmpeg -y -re -i $ -vcodec copy -acodec copy -dts_delta_threshold 1000 -ar 44100 -ab 32k -f flv rtmp://10.0.0.17:1935/live/kid
Here you first ask find to look for all mp3 files in /home/ftp.
Then you feed the results to xargs. For xargs you tell it to replace input it receives with token $ in your ffmpeg string.
You can concatenate the video files to a "named pipe" and use the pipe as a source for ffmpeg.
For example:
mkfifo pipeFile # create a FIFO file (named pipe)
cat $(find /home/ftp -name "*.mp4") > pipeFile & # concatenate video files do the pipe (do not forget the "&" for running in background)
/lely/ffmpeg -y -re -i pipeFile -vcodec copy -acodec copy -dts_delta_threshold 1000 -ar 44100 -ab 32k -f flv rtmp://10.0.0.17:1935/live/kid # run ffmpeg with the pipe as the input
Notes:
The order of files in the input will be that the find generates. You can add a "sort" command after the find to produce files in a sorted manner.
I have not tested this, since a I do not have ffmpeg installed. However, it should work :-)

ffmpeg correct audio streams when appending

I am appending 2 mp4 files together using the following routine:
ffmpeg -y -i one.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy one.ts
ffmpeg -y -i two.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy two.ts
cat one.ts two.ts >> joined.ts
ffmpeg -y -i joined.ts -vcodec copy -acodec copy -absf aac_adtstoasc joined.mp4
This works fine, however when one.mp4 has no audio stream (the file is created using ffmpeg from a single jpeg, so no sound), the routine appends the files but the audio of two.mp4 starts at the beginning of the video. how should I solve this problem? Should I add switches to my append routine so that the audio in two.mp4 starts playing where it should, or should I add something to the ffmpeg command which creates the video from jpg?
here is the command I use to create one.mp4 which contains no sound:
ffmpeg -y -loop 1 -i blah.jpg -t 3 -vcodec libx264 one.mp4

How to script this, so output is used as input?

I would like to script this command
ffmpeg -i concat:file1.mp3\|file2.mp3 -acodec copy output.mp3
which merges file1.mp3 and file2.mp3 to become output.mp3.
The problem is that I have a lot more than 2 files that I would like to merge.
Example
ffmpeg -i concat:file1.mp3\|file2.mp3 -acodec copy output1.mp3
ffmpeg -i concat:output1.mp3\|file3.mp3 -acodec copy output2.mp3
ffmpeg -i concat:output2.mp3\|file4.mp3 -acodec copy output3.mp3
ffmpeg -i concat:output3.mp3\|file5.mp3 -acodec copy output4.mp3
output4.mp3 is the result I am looking for.
The files are not actually nicely called "file" adn then a number, but ls lists them in the order they should be merged in.
Question
How can this be scripted, so I can execute it in a directory with either an even or odd number of files?
if ffmpeg supports more then two files and no file contains |, and there are not too many, you can do:
ffmpeg -i concat:"$(ls|tr '\n' '|')" -acodec copy out.mp3
if not:
for cfile in *.mp3; do
ffmpeg -i concat:myout.mp3tmp1\|$cfile -acodec copy myout.mp3tmp2
mv myout.mp3tmp2 myout.mp3tmp1
done
mv myout.mp3tmp1 <your final file name>
If you can just concatenate all files in one wash, that'd be best. But a generic answer for your Bash question:
ffmpeg -i concat:file1.mp3\|file2.mp3 -acodec copy output1.mp3
for i in $(seq 1 10); do
ffmpeg -i concat:output${i}.mp3\|file$((i + 2)).mp3 -acodec copy output$((i + 1)).mp3
done
Here 10 is two less than your total number of input files.

Resources