Re: use ffmpeg to add titles to video files
Quote:
sounds just like a for loop, except I can see some situations where it would save on typing
well, loop body is the same in both cases, but really for is less flexible when it comes to data parsing. While read saves not only typing, but also worrying about unexpected effects of IFS modifications.
read -d <char> defines what symbol should be used as a record/line delimiter (default \n)
IFS before read defines field separator, in other words how to cut contents of the record into separate fields so they can be packed into listed variables
Code:
$ while IFS=, read -d. x y z; do echo "->($x)($y)($z)"; done <<< "a,b,c.d,e,f.g,h,i."
->(a)(b)(c)
->(d)(e)(f)
->(g)(h)(i)
Quote:
what's an example of this workaround?
http://mywiki.wooledge.org/BashFAQ/001
Code:
while read -r -u9 line
do
cat > ignoredfile
echo "$line"
done 9< "$file"
standard file descriptors are 0, 1, 2 (stdin/stdout/stderr). Using some other number makes the loop go out of the way of other programs that might want to use these.
Re: use ffmpeg to add titles to video files
Quote:
Originally Posted by
Vaphell
well, loop body is the same in both cases, but really
for is less flexible when it comes to data parsing.
While read saves not only typing, but also worrying about unexpected effects of IFS modifications.
read -d <char> defines what symbol should be used as a record/line delimiter (default \n)
IFS before
read defines field separator, in other words how to cut contents of the record into separate fields so they can be packed into listed variables
Code:
$ while IFS=, read -d. x y z; do echo "->($x)($y)($z)"; done <<< "a,b,c.d,e,f.g,h,i."
->(a)(b)(c)
->(d)(e)(f)
->(g)(h)(i)
when you use an example like that, for certainly seems much less powerful
Quote:
http://mywiki.wooledge.org/BashFAQ/001
Code:
while read -r -u9 line
do
cat > ignoredfile
echo "$line"
done 9< "$file"
standard file descriptors are 0, 1, 2 (stdin/stdout/stderr). Using some other number makes the loop go out of the way of other programs that might want to use these.
I'll have to remember that trick
I changed the script to a new version. I had some issues with how I was handling titles that weren't apparent because of my file structure, but I got it all sorted now
edit: I did notice that $f{##/*} doesn't work for some reason
Re: use ffmpeg to add titles to video files
Quote:
edit: I did notice that $f{##/*} doesn't work for some reason
it, as you've written it here, has 2 things wrong:
- f is outside {} (probably a typo)
- ##/* is a bad expression, because there are only 2 scenarios for it and both don't make any sense.
- value starts with / -> expression will delete everything
Code:
$ f=/abc.def
$ echo ${f##/*}
$
- value doesn't start with / -> nothing happens
Code:
$ f=abc.def
$ echo ${f##/*}
abc.def
$
what did you expect to achieve here?
Re: use ffmpeg to add titles to video files
no, it just doesn't work, when I was testing it it did nothing
Code:
tye@T:~$ a=aaa.bbb.ccc.ddd
tye@T:~$ echo ${a##.*}
aaa.bbb.ccc.ddd
tye@T:~$ echo ${a#.*}
aaa.bbb.ccc.ddd
Re: use ffmpeg to add titles to video files
new version with file size checking, in case ffmpeg has an error:
(since I can no longer edit the original post)
I also split the ffmpeg job into a separate script, so the location of that needs to be specified in the first script
tagVideos.sh
Code:
#!/bin/bash
tagVideosCore=$HOME/Launchers/tagVideosCore.sh
while read -r f
do
# the file path of our hidden temporary file.
nF=${f%/*}/.${f##*/}
# create title suggestion for this file.
# strip the file extension and folder path
Title=${f%.*}; Title=${Title##*/}
# auto populate 'Show Title S##E##: Episode Title' for filenames using that
# structure. the episode title will be missing if it is not present in the file
# name. also, there is no filtering of either the show title or the episode title
# so that will need to be done in advance.
if [[ "$Title" =~ [sS][0-9]{1,2}[eE][0-9]{2} ]]; then
Title=$(echo "$Title" | sed 's|\(.*\)[ .]\([sS][0-9]\{2\}[eE][0-9]\{2\}\)|\1 \U\2: |')
# check if there is an episode name following the episode number.
if [[ ! "$Title" =~ [eE][0-9]{2}$ ]]; then
# if there is, filter out a separating '.' if one exists.
Title=$(echo "$Title" | sed 's|\([eE][0-9]\{2\}: \)\.|\1|')
fi
fi
# prompt user for new title.
Title=$(zenity --entry --title="Video Title" --text="Enter a new title for the video file $Title." --entry-text="$Title")
# if no title (i.e. user hit 'Cancel' during the Zenity popup), skip.
if [ ! -n "$Title" ]; then
continue
fi
# use ffmpeg to re-encode with new tag.
gnome-terminal -x $tagVideosCore "$f" "$nF" "$Title"
echo tagging video file with ffmpeg, refer to fout.txt to see results >> out.txt
done < <(echo "$NAUTILUS_SCRIPT_SELECTED_URIS" | grep -iE '.avi$|.mp4$|.mkv$' | sed 's|%20| |g')
exit
tagVideosCore.sh
Code:
#!/bin/bash
echo tagging video file "$1" >> fout.txt
echo ffmpeg -i "$1" -metadata title="$3" -acodec copy -vcodec copy -scodec copy "$2"
ffmpeg -i "$1" -metadata title="$3" \
-acodec copy -vcodec copy -scodec copy "$2"
file_f=$(stat -c %s "$1")
file_nF=$(stat -c %s "$2")
if [ "$file_nF" -gt "$file_f" ]; then
echo new file "$2" larger than old file, deleting old file >> fout.txt
rm -f "$1"
else
echo new file "$2" not larger than old file, skipping >> fout.txt
rm -f "$2"
fi
exit
Re: use ffmpeg to add titles to video files
Code:
$ a=aaa.bbb.ccc.ddd
$ echo ${a##.*} ${a##*.}
aaa.bbb.ccc.ddd ddd
$ echo ${a#.*} ${a#*.}
aaa.bbb.ccc.ddd bbb.ccc.ddd
you are doing it wrong ;-) Of course nothing happens, your example string doesn't start with . and your pattern .* says 'dot+anything'. There is no dot on the left, iiight? ;-) But even if there was, the expression would simply consume dot (#) or everything (##): . at 1st position would satisfy . in the pattern, * would match (## - the rest of string, # - nothing). Result = (## everything is axed, # dot is trimmed)
Code:
$ a=.aaa.bbb.ccc.ddd
$ echo "(${a#.*})(${a##.*})"
(aaa.bbb.ccc.ddd)()
Quote:
Code:
nF=$(echo "$f" | sed 's|\(.*/\).*$|\1|').$(echo "$f" | sed 's|.*/\(.*\)$|\1|')
Code:
nF=${f%/*}/.${f##*/}
example:
Code:
$ f=/abc/def/ghi.avi
$ echo "$f -> ${f%/*}/.${f##*/}"
/abc/def/ghi.avi -> /abc/def/.ghi.avi
Quote:
Code:
Title=$(echo "${f%.*}" | sed 's|.*/\(.*\)|\1|' )
Code:
Title=${f%.*}; Title=${Title##*/}
example
Code:
$ f=/abc/def/ghi.avi
$ Title=${f%.*}; Title=${Title##*/}
$ echo "$Title"
ghi
Re: use ffmpeg to add titles to video files
ok, I understand it now. for some reason my brain wasn't wrapping around it. but I see it now
Re: use ffmpeg to add titles to video files
i think it might be useful to use sed only to parse the name into pieces and use bash on those pieces. Greater flexibility and conditions easier to write
Code:
$ f=Some.Series.s01e12.Some.Ep.Title.avi
$ IFS=$'\t' read -r main epn ept < <( echo "${f%.*}" | sed -r 's/(.*[^. ])[. ]*([sS][0-9]{1,2}[eE][0-9]{2})[. ]*(.*)/\1\t\2\t\3/' )
$ echo ${main//./ } = ${epn^^} = ${ept//./ }
Some Series = S01E12 = Some Ep Title
sed spits out tab delimited chunks, read with IFS set to \t puts chunks into variables.