summaryrefslogtreecommitdiffstats
path: root/TOOLS/mpv_identify.sh
blob: 7b0848bffe5bbfea5ab6491308eb44d6bb853111 (plain)
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
#!/bin/sh

# file identification script
#
# manual usage:
#   mpv_identify.sh foo.mkv
#
# sh/dash/ksh/bash usage:
#   . mpv_identify.sh FOO_ foo.mkv
# will fill properties into variables like FOO_length
#
# zsh usage:
#   mpv_identify() { emulate -L sh; . mpv_identify.sh "$@"; }
#   mpv_identify FOO_ foo.mkv
# will fill properties into variables like FOO_length
#
# When multiple files were specified, their info will be put into FOO_* for the
# first file, FOO_1_* for the second file, FOO_2_* for the third file, etc.

__midentify__main() {

    case "$0" in
        mpv_identify.sh|*/mpv_identify.sh)
            # we are NOT being sourced
            [ -n "$1" ] && set -- '' "$@"
            ;;
    esac

    if [ "$#" -lt 2 ]; then
        echo >&2 "Usage 1 (for humans only): $0 filename.mkv"
        echo >&2 "will print all property values."
        echo >&2 "Note that this output really shouldn't be parsed, as the"
        echo >&2 "format is subject to change."
        echo >&2
        echo >&2 "Usage 2 (for use by scripts): see top of this file"
        echo >&2
        echo >&2 "NOTE: for mkv with ordered chapters, this may"
        echo >&2 "not always identify the specified file, but the"
        echo >&2 "file providing the first chapter. Specify"
        echo >&2 "--no-ordered-chapters to prevent this."
        return 1
    fi

    local LF="
"

    local nextprefix="$1"
    shift

    if [ -n "$nextprefix" ]; then
        # in case of error, we always want this unset
        unset "${nextprefix}path"
    fi

    local allprops="
        filename
        path
        stream-start
        stream-end
        stream-length

        demuxer

        length
        chapters
        editions
        titles

        audio
        audio-bitrate
        audio-codec
        audio-format
        channels
        samplerate

        video
        angle
        video-bitrate
        video-codec
        video-format
        video-aspect
        fps
        width
        height
        dwidth
        dheight

        sub
    "
    # TODO add metadata support once mpv can do it

    local propstr="X-MIDENTIFY-START:$LF"
    local key
    for key in $allprops; do
        propstr="${propstr}X-MIDENTIFY: $key \${=$key}$LF"
        key="$(printf '%s\n' "$key" | tr - _)"
        unset "$nextprefix$key"
    done

    local output="$(${MPV:-mpv} --term-playing-msg="$propstr" --vo=null --ao=null \
                                --frames=1 --quiet --no-cache --no-config -- "$@")"
    local fileindex=0
    local prefix=
    while :; do
        local line output
        case "$output" in
            '')
                break
                ;;
            *"$LF"*)
                line="${output%%$LF*}"
                output="${output#*$LF}"
                ;;
            *)
                line="$output"
                output=
                ;;
        esac
        case "$line" in
            X-MIDENTIFY-START:)
                if [ -n "$nextprefix" ]; then
                    prefix="$nextprefix"
                    if [ "$fileindex" -gt 0 ]; then
                        nextprefix="${prefix%${fileindex}_}"
                    fi
                    fileindex="$((fileindex+1))"
                    nextprefix="${nextprefix}${fileindex}_"
                    for key in $allprops; do
                        key="$(printf '%s\n' "$key" | tr - _)"
                        unset "$nextprefix$key"
                    done
                else
                    if [ "$fileindex" -gt 0 ]; then
                        echo
                    fi
                    fileindex="$((fileindex+1))"
                fi
                ;;
            X-MIDENTIFY:\ *)
                local key="${line#X-MIDENTIFY:\ }"
                local value="${key#* }"
                key="${key%% *}"
                key="$(printf '%s\n' "$key" | tr - _)"
                if [ -n "$nextprefix" ]; then
                    if [ -z "$prefix" ]; then
                        echo >&2 "Got X-MIDENTIFY: without X-MIDENTIFY-START:"
                    elif [ -n "$value" ]; then
                        eval "$prefix$key"='"$value"'
                    fi
                else
                    if [ -n "$value" ]; then
                        echo "$key=$value"
                    fi
                fi
                ;;
        esac
    done
}

__midentify__main "$@"