Skip to content

Instantly share code, notes, and snippets.

@deric
Last active October 19, 2020 01:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save deric/799500224ec9e35cfee8a245f0d3b16e to your computer and use it in GitHub Desktop.
Save deric/799500224ec9e35cfee8a245f0d3b16e to your computer and use it in GitHub Desktop.
Converts directory of mov files to DaVinci Resolve compatible format (tested on DaVinci Resolve 15 on Linux)
#!/bin/bash
set -o errexit -o nounset -o pipefail
export LC_ALL=C
# Convert video files to DaVinci Resolve compatible format
#
# Author: deric
#
function -h {
cat <<USAGE
Convert video files (using ffmpeg) to DaVinci Resolve compatible format
-i / --input File or directory
-ie / --input_ext Filter by input extension
-o / --output File or directory
-ac / --audio_codec Audio codec (default: pcm_s16le)
-vc / --video_codec Video codec (default: dnxhd)
-vf / --video_format Video format (default: none)
-fmt / --pixel_format Pixel format (default: yuv422p)
-bw / --bandwith Bit rate for the encoder to use e.g. 120M
-r / --rate Rate (default: 30000/1001)
-e / --format Video format e.g. mov (normally autodetected)
-f / --force Overwrite existing target
-v / --verbose debugging output
Examples:
[dnxhd @ 0000000002be23a0] Frame size: 1920x1080p; bitrate: 115Mbps; pixel format: yuv422p; framerate: 24000/1001
-vf format="scale=-1:1080,pad=1920:1080:(ow-iw)/2:0" -r 24000/1001 -bw 115M -fmt yuv422p
-vf scale=1920x1080:flags=lanczos
-vf scale=480:320,setdar=4:3
USAGE
}; function --help { -h ;}
function msg { out "$*" >&1 ;}
function out { printf '%s\n' "$*" ;}
function err { local x=$? ; msg "$*" ; return $(( $x == 0 ? 1 : $x )) ;}
# make sure output directory exists
function ensure_output {
local out=$1
local path
if [[ $out == *"/"* ]]; then
# path till last occurance of '/'
out="${out#*}"
path="${out%/*}"
else
path=$1
fi
mkdir -p "${path}"
echo $path
}
function main {
local verbose=false
local force=false
local input=""
local input_ext=""
local output=""
local audio_codec="pcm_s16le"
local video_codec="dnxhd"
local video_format=""
local format=""
local bandwith=""
local rate=""
local pixel_format="yuv422p"
while [[ $# -gt 0 ]]
do
case "$1" in # Munging globals, beware
-ac|--audio_codec) audio_codec="$2"; shift 2 ;;
-i|--input) input="$2"; shift 2 ;;
-ie|--in_ext) input_ext="$2"; shift 2 ;;
-e|--format) format="$2"; shift 2 ;;
-f|--force ) force=true; shift 1 ;;
-o|--output) output="$2"; shift 2 ;;
-vc|--video_codec) video_codec="$2"; shift 2 ;;
-vf|--video_format) video_format="$2"; shift 2 ;;
-fmt|--pixel_format) pixel_format="$2"; shift 2 ;;
-bw|--bandwith) bandwith="$2"; shift 2 ;;
-v|--verbose) verbose=true; shift 1 ;;
*) --help; err 'Argument error. Please see help: -h';;
esac
done
if [[ $verbose == true ]]; then
set -ex
fi
local output_dir
# create output directory, if missing
if [[ -z "${output}" ]]; then
err "missing output directory, use: -o / --output to specify destination"
else
output_dir=$(ensure_output $output)
fi
# TODO: findout target name
# -map_metadata 0 : copy metadata
local cmd="-map_metadata 0 -vcodec $video_codec -acodec $audio_codec -pix_fmt $pixel_format"
if [ ! force ]; then
cmd+=" -n" # do not overwrite target file
fi
# video format
if [[ ! -z "$video_format" ]];then
cmd+=" -vf $video_format"
fi
local ext="mov"
# video format mov/mp4
if [[ ! -z "$format" ]]; then
cmd+=" -f $format"
ext=$format
fi
# rate
if [[ ! -z "$rate" ]];then
cmd+=" -r $rate"
fi
if [[ ! -z "$bandwith" ]];then
cmd+=" -b:v $bandwith"
fi
if [[ -f $input ]]; then
local filename=$(basename $input)
# replace extension
local output="${output_dir}/${filename%.*}.${ext}"
local command="ffmpeg -i $input $cmd ${output}"
echo $command
`$command`
elif [[ -d $input ]]; then
local fnd="find ${input} -type f"
if [[ ! -z "${input_ext}" ]]; then
fnd+=" -name \"*.${input_ext}\""
fi
for file in $($fnd); do
[ -e "$file" ] || continue
# make sure to use "correct" extension
local filename=$(basename $file)
local output="${output_dir}/${filename%.*}.${ext}"
if $force; then
if [ -f $output ]; then
rm "$output"
fi
fi
local command="ffmpeg -i $file $cmd $output"
echo $command
`$command`
msg "=== DONE"
done
else
err "'$input' does not exist"
fi
}
if [[ ${1:-} ]] && declare -F | cut -d' ' -f3 | fgrep -qx -- "${1:-}"
then
case "$1" in
-h|--help) : ;;
*) ;;
esac
"$@"
else
main "$@"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment