I'm planning to convert a couple of video files my father has recored from *.TS to *.mkv. Since he has given me about 100 files I'd like to use a simple shell script. Basically I'd like to loop through the files, convert each file and remove the corresponding *.TS file. However, some files cannot be easily converted and I need to convert them to *.mp4 first, and then to *.mkv. Which is why I don't want to delete the files where the convert process didn't work. Therfore, I can't use a simple for , do && . I somehow need to check command1's return value. Is there a simple solution for this problem?
You probably going have to be more specific on the conditions for file conversion, but here a is a script that I used (convert mkv 10bit to mkv 8bit) that might be useful to start:
#!/bin/bash
find $1 -iname '*.mkv' | while read f ; do
if ffprobe "$f" 2>&1 | grep "High 10"; then
echo "CONVERTING: $f"
x264 --preset veryfast --tune animation --crf 16 -o "${f%*.mkv}"-8bit.mkv "$f"
mkvmerge -o "${f%*.mkv} [8bit].mkv" -D "$f" "${f%*.mkv}"-8bit.mkv
rm "${f%*.mkv}-8bit.mkv"
if [ -f "${f%*.mkv} [8bit].mkv" ]; then
rm "$f"
fi
fi
done
I use the find command to scan sub folders and give me the full path, the ${f%*.mkv} part gives filename without the extension and I know the output file will be the filename with the suffix ' [8bit].mkv' so I verify if exists and if it does, it deletes the original.
thanks, I'll try something similar
You can use the variable $?
to check return value of the previous command.
Between that and @nakamura's post, you should be able to put something together.
It's important to note that MKV is a container. Don't confuse it with a format. You could have a .mkv file that contains TS streams in it. Based on what you're asking for, it sounds like you want an H.264 or H.265 stream inside the mkv container.
You absolutely can.
# this will have the entire script stop on failure,
# so there is no reason for you to do any checks.
set -e
find $1 -iname '*.ts' | while read f ; do
avconv -i $f -c:a copy -c:v copy ${f%*.ts}.mp4
avconv -i ${f%*.ts}.mp4 -c:a copy -c:v copy ${f%*.ts}.mkv
done
EDIT: This isn't tested, but it's non-destructive, so I would use a test file and test directory before you run this against all your files. Just to be sure.
Thanks again. Yeah, I know that MKV is a container, I was a bit sloppy though^^
The actual video format remains the same.
Concerning your script: To delete the the files I'd have to do the following:
# this will have the entire script stop on failure,
# so there is no reason for you to do any checks.
set -e
find $1 -iname '*.ts' | while read f ; do
avconv -i $f -c:a copy -c:v copy ${f%*.ts}.mp4
rm -f $f
avconv -i ${f%*.ts}.mp4 -c:a copy -c:v copy ${f%*.ts}.mkv
rm -f ${f%*.ts}.mp4
done
That should work.
Glad to help!
Just in case someone else is interested, I went with the following script:
#! /bin/bash
for f in *.*; do
if [ ${f: -4} == ".TS4" ] || [ ${f: -3} == ".TS" ]
then
ffmpeg -i "$f" -sn -codec copy "${f%.*}.mkv"
# check if conversion was successful
rc=$?
if [ $rc == 0 ]
then
rm -f "$f"
else
ffmpeg -i "$f" -sn -codec copy "${f%.*}.mp4"
rm -f "$f"
ffmpeg -i "${f%.*}.mp4" -sn -codec copy "${f%.*.mkv}"
rm -f "${f%.*}.mp4"
fi
fi
done