I'm a newbie to linux scripting and am having an issue with a script that I got from the web and am trying to modify.
Here is the script
#!/bin/bash
if (($# ==0))
then
echo "Usage: flvto3gp [flv files] ..."
exit
fi
while (($# !=0 ))
do
ffmpeg -ss 00:00:10 -t 1 -s 400x300 -i $1 -f mjpeg /home/zavids/rawvids/thumbs/$1.jpg
shift
done
echo "Finished"
echo "\"fakap all those nonsense!\""
echo ""
So I'm grabbing a screenshot from a video and saving it as a jpeg. The problem is the extension of the video file is retained so finished file is video.flv.jpg (for example). How can I get rid of that video extension?
Change this line
ffmpeg -ss 00:00:10 -t 1 -s 400x300 -i $1 -f mjpeg /home/zavids/rawvids/thumbs/$1.jpg
to this
ffmpeg -ss 00:00:10 -t 1 -s 400x300 -i $1 -f mjpeg /home/zavids/rawvids/thumbs/${1%.*}.jpg
That strips the extension from the input file before using it to create the name of the output file, using bash parameter expansion.
You can try to use this :
${string%substring}
It deletes shortest match of $substring from back of $string.
For your case :
${1%.flv}
This code will substitute .flv from the end of your first argument.
You can have a lot of details here too : http://tldp.org/LDP/abs/html/string-manipulation.html
Related
I often create bash scripts with bash and pipe the results to bash... When I do this:
echo -e "ffmpeg -loglevel quiet -f lavfi -i nullsrc -t 1 -f null /dev/null\necho foo"|bash
I get
bash: line 2: cho: command not found
Where did the 'e' of 'echo' go? What does ffmpeg do there? Other commands work fine.
Note also:
echo -e "ffmpeg -loglevel quiet -f lavfi -i nullsrc -t 1 -f null /dev/null\necho foo" > /tmp/foo.sh
bash /tmp/foo.sh #works
bash < /tmp/foo.sh #doesn't
ffmpeg also reads from standard input, which it inherits from its parent process, which is the bash process reading your command line. This means ffmpeg is reading the e from echo following the new line.
One fix is to redirection standard input for ffmpeg:
echo -e "ffmpeg -loglevel quiet -f lavfi -i nullsrc -t 1 -f null /dev/null < /dev/null \necho foo"|bash
However, I can't help but point out that there isn't really any reason to run a script like this. If you want it in a separate process, start a subshell:
(
ffmpeg -loglevel quiet -f lavfi -i nullsrc -t 1 -f null /dev/null
echo foo
)
Is it possible to check if a video file has a subtitle using bash and get a simple answer like "yes" or "no". I don't need to know any details about the subtitles.
Maybe using ffmpeg?
This should display a 0 if subtitles are found, and 1 if not found.
ffmpeg -i video -c copy -map 0:s:0 -frames:s 1 -f null - -v 0 -hide_banner; echo $?
Bash
ffmpeg -i $filename 2>&1 | grep "Subtitle:"
Powershell
ffmpeg -i $filename 2>&1 | select-string "Subtitle:"
Explanation:
The ffmpeg command fails if no output file is provided, but the error message contains all information about the input file. The expression 2>&1 redirects error stream to standard output so it can be piped into grep/select-string command.
The ffmpeg docs for concat lists the following way
ffmpeg -f concat -i mylist.txt -c copy output
The mylist.txt file contains file like
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'
What I am looking is for a way to do this concat in a persistent way where the number of files can keep increasing, for example in livestreaming
I will be sending chunks of video (mp4 files) of 10 seconds each to my server and want to concat/stitch them together to output to a RTMP stream (for livestreaming)
If concat is not the proper way to do this, please suggest alternatives.
Really interested to know how people use the above concept (I hope its how it works) to send video chunks from mobile device for livestreaming
The ffmpeg docs have an example that does exactly what you're asking: https://trac.ffmpeg.org/wiki/Concatenate
This is their example:
#!/bin/bash
fn_concat_init() {
echo "fn_concat_init"
concat_pls=`mktemp -u -p . concat.XXXXXXXXXX.txt`
concat_pls="${concat_pls#./}"
echo "concat_pls=${concat_pls:?}"
mkfifo "${concat_pls:?}"
echo
}
fn_concat_feed() {
echo "fn_concat_feed ${1:?}"
{
>&2 echo "removing ${concat_pls:?}"
rm "${concat_pls:?}"
concat_pls=
>&2 fn_concat_init
echo 'ffconcat version 1.0'
echo "file '${1:?}'"
echo "file '${concat_pls:?}'"
} >"${concat_pls:?}"
echo
}
fn_concat_end() {
echo "fn_concat_end"
{
>&2 echo "removing ${concat_pls:?}"
rm "${concat_pls:?}"
# not writing header.
} >"${concat_pls:?}"
echo
}
fn_concat_init
echo "launching ffmpeg ... all.mkv"
timeout 60s ffmpeg -y -re -loglevel warning -i "${concat_pls:?}" -pix_fmt yuv422p all.mkv &
ffplaypid=$!
echo "generating some test data..."
i=0; for c in red yellow green blue; do
ffmpeg -loglevel warning -y -f lavfi -i testsrc=s=720x576:r=12:d=4 -pix_fmt yuv422p -vf "drawbox=w=50:h=w:t=w:c=${c:?}" test$i.mkv
fn_concat_feed test$i.mkv
((i++));
echo
done
echo "done"
fn_concat_end
wait "${ffplaypid:?}"
echo "done encoding all.mkv"
I try to concatenate several webm files with command below and it works (in my case)
ffmpeg -i chunk.1.webm -i chunk.2.webm -i chunk.3.webm -i chunk.4.webm -filter_complex "[0:0] [1:0] [2:0] [3:0] concat=n=4:v=1:a=0 [v]" -map "[v]" filter.webm -y
Using ffmpeg to combine small mp4 chunks?
I searching for a script that contains all of that attributes like the title.
I have done one simple but that is only for one attribute so far and i do not want one script for each of all attributes to not be confused.
Like this, running the script for like 10 minutes to see if there is any file that consist .flv and the automatic doing a convert for the file to a mp4 attribute.
#!/bin/bash
# Convert all flv to mp4
ext=.mp4
for file in *.flv; do
currmov=$file$ext
ffmpeg -r 15 -i $file -b 296k -s 640x320 -vcodec mpeg4 -acodec aac $currmov
done
Thanks for help!
/M
For all extensions:
for file in *.{flv,avi,mp3,mkv}; do
target="${file%.*}.mp4"
[[ -f "$target" ]] && { echo "skipping $file - $target exists" ; continue; }
echo ffmpeg -r 15 -i "$file" -b 296k -s 640x320 -vcodec mpeg4 -acodec aac "$target"
done
remove the echo before ffmpeg if satisfied
You just need a second loop
for ext in avi mp3 flv mk4; do
for file in *.$ext; do
...
done
done
I'm writing a little script to use the webcam on the laptop and then email across the photo to me. The ffmpeg usage has to have a exit code for it to work so with this exit the mail function will not get called. What am I doing wrong?
#!/bin/bash
MAIL_ADDR=user#example.com
ts=`date +%s`
list=$(ls | tail -n 1)
function mcheese(){
mkdir /tmp/cheese
cd /tmp/cheese
echo -e "Cheese " | mutt -s "$TS Cheese" $MAIL_ADDR -a $list
}
function cheese(){
ffmpeg -f video4linux2 -s vga -i /dev/video0 -vframes 3 /tmp/cheese/vid-$ts.%01d.jpg
exit 0
}
cheese
mcheese
You setup list in one directory, then change directory and use it.
This is unlikely to work.
Use bash -x to work out where your script is actually failing.