Last active
October 19, 2020 01:34
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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