about summary refs log tree commit diff
path: root/Completion/Unix/Command/_ffmpeg
blob: 1c57e3b9c659a19b9b367aa21b5790fe3e07df4c (plain) (blame)
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#compdef ffmpeg

local context state line
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() {
    local presets
    presets=(~/.ffmpeg/*.ffpreset(:t:r) "$FFMPEG_DATADIR"/*.ffpreset(:t:r))
    _ffmpeg_compadd 'select preset' presets ''
}

_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 ''
}

_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 ''
}

_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 ''
}

_ffmpeg_list_pix_fmts() {
    print -l ${${(M)${(f)"$(ffmpeg -pix_fmts 2>/dev/null)"}:#[I.]*}//(#b)??????([^[:space:]]##)*/$match[1]}
}

_ffmpeg_pix_fmts() {
    local pix_fmts
    pix_fmts=($(_ffmpeg_list_pix_fmts))
    _ffmpeg_compadd 'set pixel format' pix_fmts ''
}

_ffmpeg_bsfs() {
    local bsfs
    bsfs=(${${(f)"$(ffmpeg -bsfs 2>/dev/null)"}:#*:})
    _ffmpeg_compadd 'set bitstream filter' bsfs ''
}

_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;
    }
}
print_opt();
exit;

sub escape_str {
    $_[0] =~ s/:/\\:/g;
}

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);
    }
}
')"
_ffmpeg_argspecs=(${(f)_ffmpeg_argspecs})

_arguments -S \
    "${_ffmpeg_argspecs[@]}" \
    '*:output file:_files' \
    && 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

[[ "$state" == "format" ]] &&
 _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

return 1