-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathxfade
executable file
·135 lines (106 loc) · 4.52 KB
/
xfade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/sh
#===============================================================================
# xfade
# ffmpeg xfade transitions
#===============================================================================
# dependencies:
# ffmpeg ffprobe bc
#===============================================================================
# script usage
#===============================================================================
usage()
{
# if argument passed to function echo it
[ -z "${1}" ] || echo "! ${1}"
# display help
echo "\
# ffmpeg xfade transitions
$(basename "$0") -a clip1.(mp4|mkv|mov|m4v) -b clip2.(mp4|mkv|mov|m4v) -d duration -t transition -f offset -o output.mp4
-a clip1.(mp4|mkv|mov|m4v) : first clip
-b clip2.(mp4|mkv|mov|m4v) : second clip
-d duration : transition duration
-t transition : transition
-f offset : offset
-o output.mp4 : optional argument # if option not provided defaults to input-name-xfade-date-time
+ transitions
circleclose, circlecrop, circleopen, diagbl, diagbr, diagtl, diagtr, dissolve, distance
fade, fadeblack, fadegrays, fadewhite, hblur, hlslice, horzclose, horzopen, hrslice
pixelize, radial, rectcrop, slidedown, slideleft, slideright, slideup, smoothdown
smoothleft, smoothright, smoothup, squeezeh, squeezev, vdslice, vertclose, vertopen, vuslice
wipebl, wipebr, wipedown, wipeleft, wiperight, wipetl, wipetr, wipeup"
exit 2
}
#===============================================================================
# error messages
#===============================================================================
INVALID_OPT_ERR='Invalid option:'
REQ_ARG_ERR='requires an argument'
WRONG_ARGS_ERR='wrong number of arguments passed to script'
#===============================================================================
# check the number of arguments passed to the script
#===============================================================================
[ $# -gt 0 ] || usage "${WRONG_ARGS_ERR}"
#===============================================================================
# getopts check the options passed to the script
#===============================================================================
while getopts ':a:b:d:t:f:o:h' opt
do
case ${opt} in
a) clip1="${OPTARG}";;
b) clip2="${OPTARG}";;
d) dur="${OPTARG}";;
t) transition="${OPTARG}";;
f) offset="${OPTARG}";;
o) outfile="${OPTARG}";;
h) usage;;
\?) usage "${INVALID_OPT_ERR} ${OPTARG}" 1>&2;;
:) usage "${INVALID_OPT_ERR} ${OPTARG} ${REQ_ARG_ERR}" 1>&2;;
esac
done
shift $((OPTIND-1))
#===============================================================================
# variables
#===============================================================================
# input, input name and extension
clip1_nopath="${clip1##*/}"
clip1_name="${clip1_nopath%.*}"
# defaults
duration_default='0.5'
transition_default='fade'
outfile_default="${clip1_name}-xfade-$(date +"%Y-%m-%d-%H-%M-%S").mp4"
# offset and duration options not set
if [ -z "${offset}" ];then
# clip 1 duration to calculate default transition offset
clip1_dur=$(ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "${clip1}")
# round down decimal point
clip1_time=$(printf "%.1f\n" "${clip1_dur}")
# clip1 duration minus duration default and 0.1 seconds which is needed for the transition
offset_default=$(echo "${clip1_time}" - "${dur:=${duration_default}}" - 0.1 | bc -l)
# audio trim default match offset default
audio_trim_default=$(echo "${clip1_time}" - 0.1 | bc -l)
else
# offset and duration options set
# trim audio to match length of the duration and offset
audio_trim=$(echo "${dur} + ${offset}" | bc -l)
fi
#===============================================================================
# function
#===============================================================================
# cross fade video and audio
xfade_va () {
ffmpeg \
-hide_banner \
-stats -v panic \
-i "${clip1}" -i "${clip2}" \
-filter_complex \
"[0:v][1:v]xfade=transition='${transition:=${transition_default}}':duration='${dur:=${duration_default}}':offset='${offset:=${offset_default}}'[xfade];
[0:a]atrim=0:'${audio_trim:=${audio_trim_default}}'[atrim];
[atrim][1:a]acrossfade=d='${dur:=${duration_default}}'[afade]
" \
-map "[xfade]" -map "[afade]" \
-pix_fmt yuv420p \
-movflags +faststart -f mp4 \
"${outfile:=${outfile_default}}"
}
# run the xfade_va function
xfade_va "${clip1}" "${clip2}"