summaryrefslogtreecommitdiff
path: root/Completion/Unix/Command/_ffmpeg
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Unix/Command/_ffmpeg')
-rw-r--r--Completion/Unix/Command/_ffmpeg272
1 files changed, 153 insertions, 119 deletions
diff --git a/Completion/Unix/Command/_ffmpeg b/Completion/Unix/Command/_ffmpeg
index 1c57e3b9c..8f9b2c9cb 100644
--- a/Completion/Unix/Command/_ffmpeg
+++ b/Completion/Unix/Command/_ffmpeg
@@ -1,135 +1,166 @@
#compdef ffmpeg
-local context state line
+local context state line expl
typeset -A opt_args
-local BOLD=$'\e[1m'
-local NORM=$'\e[m'
-
-_ffmpeg_compadd() {
- compadd -X "${BOLD}$1${NORM}" -q -S "$3" -a $2
-}
-
-_ffmpeg_presets() {
+(( $+functions[_ffmpeg_presets] )) || _ffmpeg_presets() {
local presets
presets=(~/.ffmpeg/*.ffpreset(:t:r) "$FFMPEG_DATADIR"/*.ffpreset(:t:r))
- _ffmpeg_compadd 'select preset' presets ''
+ _wanted ffmpeg-presets expl 'select preset' compadd -a presets
}
-_ffmpeg_acodecs() {
+(( $+functions[_ffmpeg_acodecs] )) || _ffmpeg_acodecs() {
local acodecs
- acodecs=(${${(M)${(f)"$(ffmpeg -codecs 2>/dev/null)"}:#[[:space:]][D[:space:]][E[:space:]]A[S[:space:]][D[:space:]][T[:space:]][[:space:]][^[:space:]]##*}//(#b)????????([^[:space:]]##)*/$match[1]})
- _ffmpeg_compadd 'force audio codec (''copy'' to copy stream)' acodecs ''
+ acodecs=(copy ${${(M)${(f)"$(_call_program audio-codecs $words[1] -codecs 2>/dev/null)"}:#[[:space:]][D[:space:]][E[:space:]]A[S[:space:]][D[:space:]][T[:space:]][[:space:]][^[:space:]]##*}//(#b)????????([^[:space:]]##)*/$match[1]})
+ _wanted ffmpeg-audio-codecs expl 'force audio codec (''copy'' to copy stream)' compadd -a acodecs
}
-_ffmpeg_vcodecs() {
+(( $+functions[_ffmpeg_vcodecs] )) || _ffmpeg_vcodecs() {
local vcodecs
- vcodecs=(${${(M)${(f)"$(ffmpeg -codecs 2>/dev/null)"}:#[[:space:]][D[:space:]][E[:space:]]V[S[:space:]][D[:space:]][T[:space:]][[:space:]][^[:space:]]##*}//(#b)????????([^[:space:]]##)*/$match[1]})
- _ffmpeg_compadd 'force video codec (''copy'' to copy stream)' vcodecs ''
+ vcodecs=(copy ${${(M)${(f)"$(_call_program video-codecs $words[1] -codecs 2>/dev/null)"}:#[[:space:]][D[:space:]][E[:space:]]V[S[:space:]][D[:space:]][T[:space:]][[:space:]][^[:space:]]##*}//(#b)????????([^[:space:]]##)*/$match[1]})
+ _wanted ffmpeg-video-codecs expl 'force video codec (''copy'' to copy stream)' compadd -a vcodecs
}
-_ffmpeg_formats() {
+(( $+functions[_ffmpeg_formats] )) || _ffmpeg_formats() {
local formats
- formats=(${(ou)${=${(s:,:)${${(M)${(f)"$(ffmpeg -formats 2>/dev/null)"}:#[[:space:]][D[:space:]][E[:space:]][[:space:]][^[:space:]]##*}//(#b)????([^[:space:]]##)*/$match[1]}}}})
- _ffmpeg_compadd 'force format' formats ''
+ formats=(${(ou)${=${(s:,:)${${(M)${(f)"$(_call_program formats $words[1] -formats 2>/dev/null)"}:#[[:space:]][D[:space:]][E[:space:]][[:space:]][^[:space:]]##*}//(#b)????([^[:space:]]##)*/$match[1]}}}})
+ _wanted ffmpeg-formats expl 'force format' compadd -a formats
}
-_ffmpeg_list_pix_fmts() {
- print -l ${${(M)${(f)"$(ffmpeg -pix_fmts 2>/dev/null)"}:#[I.]*}//(#b)??????([^[:space:]]##)*/$match[1]}
+(( $+functions[_ffmpeg_list_pix_fmts] )) || _ffmpeg_list_pix_fmts() {
+ echo - ${${${(M)${(f)"$(_call_program formats $words[1] -pix_fmts 2>/dev/null)"}:#[I.][O.][H.][P.][B.] [^=[:space:]]*}#* }%% *}
}
-_ffmpeg_pix_fmts() {
+(( $+functions[_ffmpeg_pix_fmts] )) || _ffmpeg_pix_fmts() {
local pix_fmts
pix_fmts=($(_ffmpeg_list_pix_fmts))
- _ffmpeg_compadd 'set pixel format' pix_fmts ''
+ _wanted ffmpeg-pix-fmts expl 'set pixel format' compadd -a pix_fmts
}
-_ffmpeg_bsfs() {
+(( $+functions[_ffmpeg_bsfs] )) || _ffmpeg_bsfs() {
local bsfs
- bsfs=(${${(f)"$(ffmpeg -bsfs 2>/dev/null)"}:#*:})
- _ffmpeg_compadd 'set bitstream filter' bsfs ''
+ bsfs=(${${(f)"$(_call_program bsfs $words[1] -bsfs 2>/dev/null)"}:#*:})
+ _wanted ffmpeg-bsfs expl 'set bitstream filter' compadd -a bsfs
+}
+
+typeset -A _ffmpeg_flags
+
+(( $+functions[_ffmpeg_flag_options] )) || _ffmpeg_flag_options() {
+ local expl
+ _wanted options expl 'select flags' compadd -S '' -- {-,+}${^flag_options}
}
-_ffmpeg_argspecs="$(ffmpeg -h 2>/dev/null | perl -e '
-my $lastopt;
-my $lastopt_description;
-my $lastopt_takesargs;
-my @lastopt_values;
-while (<>) {
- if (/^(-\S+)\s+(\S.+)$/) {
- print_opt();
- $lastopt = $1;
- $lastopt_description = $2;
- if ($lastopt_description =~ /<\w+>/) {
- $lastopt_description =~ s/<.*?>\s+//;
- $lastopt_description =~ s/\S{5} ?//;
- $lastopt_description = $lastopt if not $lastopt_description;
- escape_str($lastopt_description);
- } elsif ($lastopt_description =~ /^(\S+)\s\s+/) {
- my $example = $1;
- $lastopt_description =~ s/^\S+\s\s+//;
- escape_str($example);
- escape_str($lastopt_description);
- if ($example eq q(filename)) {
- $lastopt_takesargs = 0;
- $lastopt .= qq(:$lastopt_description:_files);
- } elsif ($lastopt =~ /^-[asv]pre$/) {
- $lastopt_takesargs = 0;
- $lastopt .= qq(: :_ffmpeg_presets);
- } elsif ($lastopt eq q(-acodec)) {
- $lastopt_takesargs = 0;
- $lastopt .= qq(: :_ffmpeg_acodecs);
- } elsif ($lastopt eq q(-vcodec)) {
- $lastopt_takesargs = 0;
- $lastopt .= qq(: :_ffmpeg_vcodecs);
- } elsif ($lastopt eq q(-f)) {
- $lastopt_takesargs = 0;
- $lastopt .= qq(: :_ffmpeg_formats);
- } elsif ($lastopt eq q(-pix_fmt)) {
- $lastopt_takesargs = 0;
- $lastopt .= qq(: :_ffmpeg_pix_fmts);
- } elsif ($example eq q(bitstream_filter)) {
- $lastopt_takesargs = 0;
- $lastopt .= qq(: :_ffmpeg_bsfs);
- } else {
- $lastopt_takesargs = 1;
- $lastopt_description .= qq{ ($example)};
- }
- } else {
- $lastopt_takesargs = 0;
- if ($lastopt eq q(-vfilters)) {
- $lastopt .= qq(: :->vfilters);
- }
- }
- @lastopt_values = ();
- } elsif (/^ (\S+)/) {
- $lastopt_takesargs = 1;
- push @lastopt_values, $1;
- }
+(( $+functions[_ffmpeg_more_flag_options] )) || _ffmpeg_more_flag_options() {
+ compset -p $1 && _ffmpeg_flag_options
}
-print_opt();
-exit;
-sub escape_str {
- $_[0] =~ s/:/\\:/g;
+(( $+functions[_ffmpeg_new_flag_options] )) || _ffmpeg_new_flag_options() {
+ compset -P '*' && _ffmpeg_flag_options
}
-sub print_opt {
- return if not $lastopt;
-
- print qq($lastopt);
- if (!$lastopt_takesargs) {
- print qq(\n);
- } else {
- print qq(:$lastopt_description:);
- if (@lastopt_values) {
- printf qq{(%s)}, join(q( ), @lastopt_values);
- }
- print qq(\n);
- }
+(( $+functions[_ffmpeg_flags] )) || _ffmpeg_flags() {
+ local -a flag_options
+ eval "flag_options=(\${=_ffmpeg_flags[$1]})"
+
+ local match mbegin mend
+ integer ret=1
+
+ if [[ $PREFIX = (#b)(*)[-+]([^-+]#) ]]; then
+ if [[ -n ${flag_options[(R)$match[2]]} ]]; then
+ _ffmpeg_new_flag_options && ret=0
+ fi
+ if [[ -n ${flag_options[(R)$match[2]?*]} ]]; then
+ _ffmpeg_more_flag_options ${#match[1]} && ret=0
+ fi
+ else
+ _ffmpeg_flag_options && ret=0
+ fi
+
+ return $ret
+}
+
+(( $+functions[_ffmpeg_register_lastopt_values] )) || _ffmpeg_register_lastopt_values() {
+ if (( lastopt_takesargs )); then
+ lastopt+=":$lastopt_description:"
+ if (( $#lastopt_values )); then
+ if [[ $lastopt_type == flags ]]; then
+ flagtype=${${lastopt%%:*}#-}
+ lastopt+="->$flagtype"
+ _ffmpeg_flags[$flagtype]="${lastopt_values[*]}"
+ else
+ lastopt+="(${lastopt_values[*]})"
+ fi
+ fi
+ fi
+ _ffmpeg_argspecs+=$lastopt
+}
+
+local -a _ffmpeg_argspecs
+{
+ local lastopt
+ local lastopt_description
+ local lastopt_takesargs
+ local lastopt_type
+ local -a lastopt_values
+
+ _call_program options $words[1] -h 2>/dev/null | while IFS=$'\n' read -r; do
+ if [[ $REPLY == -* ]]; then
+ [[ -n $lastopt ]] && _ffmpeg_register_lastopt_values
+ lastopt=${REPLY%%[[:space:]]*}
+ lastopt_description=${REPLY##-[^[:space:]]##[[:space:]]##}
+ if [[ $lastopt_description == (#b)'<'(?##)'>'* ]]; then
+ lastopt_type=$match[1]
+ lastopt_description=${lastopt_description##<[^[:space:]]##>[[:space:]]##[^[:space:]]##[[:space:]]#}
+ if [[ -z $lastopt_description ]]; then
+ lastopt_description=$lastopt
+ fi
+ lastopt_description=${lastopt_description//:/\\:}
+ elif [[ $lastopt_description == [^[:space:]]##[[:space:]][[:space:]]* ]]; then
+ local example=${lastopt_description%% *}
+ example=${example//:/\\:}
+ lastopt_description=${lastopt_description##[^[:space:]]##[[:space:]]##}
+ lastopt_description=${lastopt_description//:/\\:}
+ if [[ $example == filename ]]; then
+ lastopt_takesargs=0
+ lastopt+=":$lastopt_description:_files"
+ elif [[ $lastopt == -[asv]pre ]]; then
+ lastopt_takesargs=0
+ lastopt+=": :_ffmpeg_presets"
+ elif [[ $lastopt == -acodec ]]; then
+ lastopt_takesargs=0
+ lastopt+=": :_ffmpeg_acodecs"
+ elif [[ $lastopt == -vcodec ]]; then
+ lastopt_takesargs=0
+ lastopt+=": :_ffmpeg_vcodecs"
+ elif [[ $lastopt == -f ]]; then
+ lastopt_takesargs=0
+ lastopt+=": :_ffmpeg_formats"
+ elif [[ $lastopt == -pix_fmt ]]; then
+ lastopt_takesargs=0
+ lastopt+=": :_ffmpeg_pix_fmts"
+ elif [[ $example == bitstream_filter ]]; then
+ lastopt_takesargs=0
+ lastopt+=": :_ffmpeg_bsfs"
+ else
+ lastopt_takesargs=1
+ lastopt_description+=" ($example)"
+ fi
+ else
+ lastopt_takesargs=0
+ if [[ $lastopt == -vfilters ]]; then
+ lastopt+=": :->vfilters"
+ fi
+ fi
+ lastopt_values=()
+ elif [[ $REPLY == ' '* ]]; then
+ REPLY=${REPLY##[[:space:]]##}
+ REPLY=${REPLY%%[[:space:]]##*}
+ lastopt_takesargs=1
+ lastopt_values+=$REPLY
+ fi
+ done
+ [[ -n $lastopt ]] && _ffmpeg_register_lastopt_values
}
-')"
-_ffmpeg_argspecs=(${(f)_ffmpeg_argspecs})
_arguments -S \
"${_ffmpeg_argspecs[@]}" \
@@ -137,27 +168,30 @@ _arguments -S \
&& return 0
[[ "$state" == "vfilters" ]] &&
- _values -s , -S = 'video filters' \
- 'aspect:set aspect ratio (rational number X\:Y or decimal number):' \
- 'crop:crop input video (x\:y\:width\:height):' \
- 'format: :->format' \
- 'noformat: :->noformat' \
- 'null' \
- 'pad:add pads to the input image (width\:height\:x\:y\:color_string):' \
- 'pixelaspect:set pixel aspect ratio (rational number X\:Y or decimal number):' \
- 'scale:scale input video (width\:height):' \
- 'slicify:output slice height ("random" or a number of pixels):' \
- 'unsharp:luma_x\:luma_y\:luma_amount\:chroma_x\:chroma_y\:chroma_amount:' \
- 'vflip' \
- 'buffer' \
- 'nullsrc' \
- 'nullsink' \
- && return 0
+ _values -s , -S = 'video filters' \
+ 'aspect:set aspect ratio (rational number X\:Y or decimal number):' \
+ 'crop:crop input video (x\:y\:width\:height):' \
+ 'format: :->format' \
+ 'noformat: :->noformat' \
+ 'null' \
+ 'pad:add pads to the input image (width\:height\:x\:y\:color_string):' \
+ 'pixelaspect:set pixel aspect ratio (rational number X\:Y or decimal number):' \
+ 'scale:scale input video (width\:height):' \
+ 'slicify:output slice height ("random" or a number of pixels):' \
+ 'unsharp:luma_x\:luma_y\:luma_amount\:chroma_x\:chroma_y\:chroma_amount:' \
+ 'vflip' \
+ 'buffer' \
+ 'nullsrc' \
+ 'nullsink' \
+ && return 0
[[ "$state" == "format" ]] &&
- _values -s : -S = 'convert input video to one of the specified pixel formats' $(_ffmpeg_list_pix_fmts) && return 0
+ _values -s : -S = 'convert input video to one of the specified pixel formats' $(_ffmpeg_list_pix_fmts) && return 0
[[ "$state" == "noformat" ]] &&
- _values -s : -S = 'disable specified pixel formats by force' $(_ffmpeg_list_pix_fmts) && return 0
+ _values -s : -S = 'disable specified pixel formats by force' $(_ffmpeg_list_pix_fmts) && return 0
+
+[[ -n $state && -n $_ffmpeg_flags[$state] ]] &&
+ _ffmpeg_flags $state && return 0
return 1