-
Notifications
You must be signed in to change notification settings - Fork 1
/
lapse
executable file
·133 lines (127 loc) · 3.49 KB
/
lapse
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
#!/usr/bin/env bash
#
# lapse - bash wrapper around FFMPEG
#
# Copyright 2014 Ben Thornton
#
# Released under the GPLv2.
# Combine still photos into a video.
function stills2vid {
if [ $# -lt 2 ]; then
echo "usage: $0 <input-dir> <output-dir> [<quality>]" >&2
return
fi
# 1st argument is the source directory (e.g. path/to/DCIM) for the stills.
if [ ! -d "$1" ]; then
echo "$1 is not a directory" >&2
return
fi
if [ ! -r "$1" ]; then
echo "$1 is not readable" >&2
return
fi
# 2nd argument is the target path for the video file.
if [ -e "$2" ]; then
echo "$2 already exists: skipping" >&2
return
fi
# 3rd argument is the quality for the encoder to use:
# 0 : ProRes422 (Proxy)
# 1 : ProRes422 (LT)
# 2 : ProRes422 (Normal)
# 3 : ProRes422 (HQ)
# See: http://transcoding.wordpress.com/2012/01/29/prores-ffmpeg/
quality=2
if [ -n "$3" ]; then
quality="$3"
fi
if [ "$3" -lt 0 ]; then
echo "Quality cannot be negative." >&2
return
fi
if [ "$3" -gt 3 ]; then
echo "Quality cannot be above 3." >&2
return
fi
# Input looks okay. Let's render.
echo "Processing $1/G*.JPG"
ffmpeg -f image2 -pattern_type glob -i "$1/G*.JPG" -r 29.97 -q:v "$3" -vcodec prores -profile:v 0 -an "$2"
# Quit if there's an error, of if the user insisted by pressing control c.
error=$?
if [ "$error" -ne 0 ]; then
echo "fatal: FFMPEG halted" >&2
exit $error
fi
}
if [ $# -lt 2 ]; then
echo "usage: $0 <input-dir> <output-dir> [<quality>]" >&2
echo "<quality> must be an integer from 0-3 inclusive." >&2
echo "[0] ProRes 422 Proxy 30% of [2]" >&2
echo "[1] ProRes 422 LT 70% of [2]" >&2
echo "[2] ProRes 422 (Default)" >&2
echo "[3] ProRes 422 HQ (Best quality)" >&2
echo "example 1: $0 /path/to/DCIM ~/Movies"
echo "example 2: $0 /path/to/DCIM ~/Movies 3"
exit 1
fi
# Where can we find the input?
source="$1"
if [ ! -d "$source" ]; then
echo "fatal: source is not a directory: $source" >&2
exit 2
fi
if [ ! -r "$source" ]; then
echo "fatal: cannot read from source: $source" >&2
exit 3
fi
echo "Source directory is: $source"
# Where should we save the output?
path=$(ls -d "$source" | head -n1)
file=$(ls "$path" | head -n1)
date=$(stat -f "%Sm" -t "%Y-%m-%d" "$path/$file")
target="$2"
if [ ! -d "$2" ]; then
echo "Target directory does not exist." >&2
mkdir -p "$2"
if [ $? -ne 0 ]; then
echo "fatal: cannot create target directory: $2" >&2
exit 4
fi
fi
target="$target/$date"
if [ ! -d "$2" ]; then
mkdir -p "$2"
if [ $? -ne 0 ]; then
echo "fatal: cannot create target directory: $2" >&2
exit 5
fi
fi
if [ ! -w "$2" ]; then
echo "fatal: cannot write to target: $2" >&2
exit 6
fi
echo "Target directory is: $2"
# Render each directory of photos into a video.
for dir in $(ls "$source"); do
stills2vid "$source/$dir" "$2/$dir.mov" "$quality"
done
# Concatenate the video files into one.
final="$final/$date.mov"
if [ -e "$final" ]; then
echo "fatal: $final already exists" >&2
exit 7
fi
echo "Concatenating files into: $final"
list="/tmp/lapse.tmp"
echo "" > "$list.unsorted"
for v in $(find "$2" -name '*.mov'); do
echo "file '$v'" >> "$list.unsorted"
done
sort "$list.unsorted" > "$list"
rm "$list.unsorted"
wc -l "$list"
head "$list"
echo "[...]"
tail "$list"
ffmpeg -f concat -i "$list" -c copy "$final"
rm "$list"