summaryrefslogtreecommitdiff
path: root/vjas
blob: d4fb2ef2d834457bbefcdea5c3d840fad157b7e5 (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
#!/bin/bash
#
# Join and encode video N-times faster.
#

set -e

# VARIABLES

SELFNAME=$(basename $0)

# FUNCTIONS

cleanup() {
    rm -f "$CONCAT_FILE"
}

get_video_filter() {
    echo "setpts=PTS/$1"
}

get_audio_filter() {
    bc <<END
scale = 6
max = $1
f = 1
while (f < max) {
    if (f * 2 > max) {
        break;
    }
    if (f > 1) {
        print ","
    }
    print "atempo=2.0"
    f *= 2
}
if (f == max) {
} else {
    print ",atempo=", max/f
}
END
}

die() {
    printf "%s\n" "$1" >&2
    exit 1
}

print_help() {
    cat >&2 <<END
Usage: $SELFNAME [OPTIONS]... [FILE]...

    Join and speed up video files.

Options:
    -s, --speed     speed up factor (min is 2)
    -o, --output    output file name (random .mp4 by default)

Example:
    Speed up 16-times all MTS files in current directiory
        $SELFNAME -s 16 -o out.mp4 *.MTS
END
}

# MAIN

trap cleanup EXIT

while [[ $1 = -* ]] ; do
    case "$1" in
        -s|--speed)
            SPEED="$2"
            [[ "$SPEED" -ge 2 ]] || die "Error: Speed not integer or less then 2: $SPEED"
            shift
            ;;
        -o|--output)
            OUTPUT="$2"
            shift
            ;;
        -h|--help)
            print_help
            exit
            ;;
        --)
            shift
            break
            ;;
        *)
            die "Error: Unknown option: $1"
            ;;
    esac
    shift
done

[[ -z "$SPEED" ]] && die "No speed set.  See help for details"

VIDEO_FILTER=$(get_video_filter $SPEED)
AUDIO_FILTER=$(get_audio_filter $SPEED)

echo "Files to process (in order):"
for f in $* ; do
    echo "  $f"
done
read -p 'Press Enter to continue.'

CONCAT_FILE=$(tempfile -d .)
for f in $* ; do
    echo "file '$f'" >> "$CONCAT_FILE"
done

[[ -z "$OUTPUT" ]] && OUTPUT=$(tempfile -d . --suffix .mp4)

ffmpeg -f concat -i "$CONCAT_FILE" \
    -strict -2 \
    -c:v libx264 -preset slow -crf 22 \
    -c:a aac -b:a 128k \
    -filter_complex "[0:v]$VIDEO_FILTER[v];[0:a]$AUDIO_FILTER[a]" \
    -map "[v]" -map "[a]" \
    -y "$OUTPUT"