UNPKG

9.63 kBMarkdownView Raw
1# Creating Content
2
3## Commands for creating tests streams
4
5### Streams with EXT-X-PROGRAM-DATE-TIME for testing seekToProgramTime and convertToProgramTime
6
7lavfi and testsrc are provided for creating a test stream in ffmpeg
8-g 300 sets the GOP size to 300 (keyframe interval, at 30fps, one keyframe every 10 seconds)
9-f hls sets the format to HLS (creates an m3u8 and TS segments)
10-hls\_time 10 sets the goal segment size to 10 seconds
11-hls\_list\_size 20 sets the number of segments in the m3u8 file to 20
12-program\_date\_time an hls flag for setting #EXT-X-PROGRAM-DATE-TIME on each segment
13
14```
15ffmpeg \
16 -f lavfi \
17 -i testsrc=duration=200:size=1280x720:rate=30 \
18 -g 300 \
19 -f hls \
20 -hls_time 10 \
21 -hls_list_size 20 \
22 -hls_flags program_date_time \
23 stream.m3u8
24```
25
26## Commands used for segments in `test/segments` dir
27
28### video.ts
29
30Copy only the first two video frames, leave out audio.
31
32```
33$ ffmpeg -i index0.ts -vframes 2 -an -vcodec copy video.ts
34```
35
36### videoOneSecond.ts
37
38Blank video for 1 second, MMS-Small resolution, start at 0 PTS/DTS, 2 frames per second
39
40```
41$ ffmpeg -f lavfi -i color=c=black:s=128x96:r=2:d=1 -muxdelay 0 -c:v libx264 videoOneSecond.ts
42```
43
44### videoOneSecond1.ts through videoOneSecond4.ts
45
46Same as videoOneSecond.ts, but follows timing in sequence, with videoOneSecond.ts acting as the 0 index. Each segment starts at the second that its index indicates (e.g., videoOneSecond2.ts has a start time of 2 seconds).
47
48```
49$ ffmpeg -i videoOneSecond.ts -muxdelay 0 -output_ts_offset 1 -vcodec copy videoOneSecond1.ts
50$ ffmpeg -i videoOneSecond.ts -muxdelay 0 -output_ts_offset 2 -vcodec copy videoOneSecond2.ts
51$ ffmpeg -i videoOneSecond.ts -muxdelay 0 -output_ts_offset 3 -vcodec copy videoOneSecond3.ts
52$ ffmpeg -i videoOneSecond.ts -muxdelay 0 -output_ts_offset 4 -vcodec copy videoOneSecond4.ts
53```
54
55### audio.ts
56
57Copy only the first two audio frames, leave out video.
58
59```
60$ ffmpeg -i index0.ts -aframes 2 -vn -acodec copy audio.ts
61```
62
63### videoMinOffset.ts
64
65video.ts but with an offset of 0
66
67```
68$ ffmpeg -i video.ts -muxpreload 0 -muxdelay 0 -vcodec copy videoMinOffset.ts
69```
70
71### audioMinOffset.ts
72
73audio.ts but with an offset of 0. Note that muxed.ts is used because ffmpeg didn't like
74the use of audio.ts
75
76```
77$ ffmpeg -i muxed.ts -muxpreload 0 -muxdelay 0 -acodec copy -vn audioMinOffset.ts
78```
79
80### videoMaxOffset.ts
81
82This segment offsets content such that it ends at exactly the max timestamp before a rollover occurs. It uses the max timestamp of 2^33 (8589934592) minus the segment duration of 6006 (0.066733 seconds) in order to not rollover mid segment, and divides the value by 90,000 to convert it from media time to seconds.
83
84(2^33 - 6006) / 90,000 = 95443.6509556
85
86```
87$ ffmpeg -i videoMinOffset.ts -muxdelay 95443.6509556 -muxpreload 95443.6509556 -output_ts_offset 95443.6509556 -vcodec copy videoMaxOffset.ts
88```
89
90### audioMaxOffset.ts
91
92This segment offsets content such that it ends at exactly the max timestamp before a rollover occurs. It uses the max timestamp of 2^33 (8589934592) minus the segment duration of 11520 (0.128000 seconds) in order to not rollover mid segment, and divides the value by 90,000 to convert it from media time to seconds.
93
94(2^33 - 11520) / 90,000 = 95443.5896889
95
96```
97$ ffmpeg -i audioMinOffset.ts -muxdelay 95443.5896889 -muxpreload 95443.5896889 -output_ts_offset 95443.5896889 -acodec copy audioMaxOffset.ts
98```
99
100### videoLargeOffset.ts
101
102This segment offsets content by the rollover threshhold of 2^32 (4294967296) found in the rollover handling of mux.js, adds 1 to ensure there aren't any cases where there's an equal match, then divides the value by 90,000 to convert it from media time to seconds.
103
104(2^32 + 1) / 90,000 = 47721.8588556
105
106```
107$ ffmpeg -i videoMinOffset.ts -muxdelay 47721.8588556 -muxpreload 47721.8588556 -output_ts_offset 47721.8588556 -vcodec copy videoLargeOffset.ts
108```
109
110### audioLargeOffset.ts
111
112This segment offsets content by the rollover threshhold of 2^32 (4294967296) found in the rollover handling of mux.js, adds 1 to ensure there aren't any cases where there's an equal match, then divides the value by 90,000 to convert it from media time to seconds.
113
114(2^32 + 1) / 90,000 = 47721.8588556
115
116```
117$ ffmpeg -i audioMinOffset.ts -muxdelay 47721.8588556 -muxpreload 47721.8588556 -output_ts_offset 47721.8588556 -acodec copy audioLargeOffset.ts
118```
119
120### videoLargeOffset2.ts
121
122This takes videoLargeOffset.ts and adds the duration of videoLargeOffset.ts (6006 / 90,000 = 0.066733 seconds) to its offset so that this segment can act as the second in one continuous stream.
123
12447721.8588556 + 0.066733 = 47721.9255886
125
126```
127$ ffmpeg -i videoLargeOffset.ts -muxdelay 47721.9255886 -muxpreload 47721.9255886 -output_ts_offset 47721.9255886 -vcodec copy videoLargeOffset2.ts
128```
129
130### audioLargeOffset2.ts
131
132This takes audioLargeOffset.ts and adds the duration of audioLargeOffset.ts (11520 / 90,000 = 0.128 seconds) to its offset so that this segment can act as the second in one continuous stream.
133
13447721.8588556 + 0.128 = 47721.9868556
135
136```
137$ ffmpeg -i audioLargeOffset.ts -muxdelay 47721.9868556 -muxpreload 47721.9868556 -output_ts_offset 47721.9868556 -acodec copy audioLargeOffset2.ts
138```
139
140### caption.ts
141
142Copy the first two frames of video out of a ts segment that already includes CEA-608 captions.
143
144`ffmpeg -i index0.ts -vframes 2 -an -vcodec copy caption.ts`
145
146### id3.ts
147
148Copy only the first five frames of video, leave out audio.
149
150`ffmpeg -i index0.ts -vframes 5 -an -vcodec copy smaller.ts`
151
152Create an ID3 tag using [id3taggenerator][apple_streaming_tools]:
153
154`id3taggenerator -text "{\"id\":1, \"data\": \"id3\"}" -o tag.id3`
155
156Create a file `macro.txt` with the following:
157
158`0 id3 tag.id3`
159
160Run [mediafilesegmenter][apple_streaming_tools] with the small video segment and macro file, to produce a new segment with ID3 tags inserted at the specified times.
161
162`mediafilesegmenter -start-segments-with-iframe --target-duration=1 --meta-macro-file=macro.txt -s -A smaller.ts`
163
164### mp4Video.mp4
165
166Copy only the first two video frames, leave out audio.
167movflags:
168* frag\_keyframe: "Start a new fragment at each video keyframe."
169* empty\_moov: "Write an initial moov atom directly at the start of the file, without describing any samples in it."
170* omit\_tfhd\_offset: "Do not write any absolute base\_data\_offset in tfhd atoms. This avoids tying fragments to absolute byte positions in the file/streams." (see also: https://www.w3.org/TR/mse-byte-stream-format-isobmff/#movie-fragment-relative-addressing)
171
172```
173$ ffmpeg -i file.mp4 -movflags frag_keyframe+empty_moov+omit_tfhd_offset -vframes 2 -an -vcodec copy mp4Video.mp4
174```
175
176### mp4Audio.mp4
177
178Copy only the first two audio frames, leave out video.
179movflags:
180* frag\_keyframe: "Start a new fragment at each video keyframe."
181* empty\_moov: "Write an initial moov atom directly at the start of the file, without describing any samples in it."
182* omit\_tfhd\_offset: "Do not write any absolute base\_data\_offset in tfhd atoms. This avoids tying fragments to absolute byte positions in the file/streams." (see also: https://www.w3.org/TR/mse-byte-stream-format-isobmff/#movie-fragment-relative-addressing)
183
184```
185$ ffmpeg -i file.mp4 -movflags frag_keyframe+empty_moov+omit_tfhd_offset -aframes 2 -vn -acodec copy mp4Audio.mp4
186```
187
188### mp4VideoInit.mp4 and mp4AudioInit.mp4
189
190Using DASH as the format type (-f) will lead to two init segments, one for video and one for audio. Using HLS will lead to one joined.
191Renamed from .m4s to .mp4
192
193```
194$ ffmpeg -i input.mp4 -f dash out.mpd
195```
196
197### webmVideoInit.webm and webmVideo.webm
198
199```
200$ cat mp4VideoInit.mp4 mp4Video.mp4 > video.mp4
201$ ffmpeg -i video.mp4 -dash_segment_type webm -c:v libvpx-vp9 -f dash output.mpd
202$ mv init-stream0.webm webmVideoInit.webm
203$ mv chunk-stream0-00001.webm webmVideo.webm
204```
205
206### subtitlesEncrypted.vtt
207
208Run subtitles.vtt through subtle crypto. As an example:
209
210```javascript
211const fs = require('fs');
212const { subtle } = require('crypto').webcrypto;
213
214// first segment has media index 0, so should have the following IV
215const DEFAULT_IV = new Uint8Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
216
217const getCryptoKey = async (bytes, iv = DEFAULT_IV) => {
218 const algorithm = { name: 'AES-CBC', iv };
219 const extractable = true;
220 const usages = ['encrypt', 'decrypt'];
221
222 return subtle.importKey('raw', bytes, algorithm, extractable, usages);
223};
224
225const run = async () => {
226 const keyFilePath = process.argv[2];
227 const segmentFilePath = process.argv[3];
228
229 const keyBytes = fs.readFileSync(keyFilePath);
230 const segmentBytes = fs.readFileSync(segmentFilePath);
231
232 const key = await getCryptoKey(keyBytes);
233 const encryptedBytes = await subtle.encrypt({
234 name: 'AES-CBC',
235 iv: DEFAULT_IV,
236 }, key, segmentBytes);
237
238 fs.writeFileSync('./encrypted.vtt', new Buffer(encryptedBytes));
239
240 console.log(`Wrote ${encryptedBytes.length} bytes to encrypted.vtt:`);
241};
242
243run();
244```
245
246To use the script:
247
248```
249$ node index.js encryptionKey.key subtitles.vtt
250```
251
252## Other useful commands
253
254### Joined (audio and video) initialization segment (for HLS)
255
256Using DASH as the format type (-f) will lead to two init segments, one for video and one for audio. Using HLS will lead to one joined.
257Note that -hls\_fmp4\_init\_filename defaults to init.mp4, but is here for readability.
258Without specifying fmp4 for hls\_segment\_type, ffmpeg defaults to ts.
259
260```
261$ ffmpeg -i input.mp4 -f hls -hls_fmp4_init_filename init.mp4 -hls_segment_type fmp4 out.m3u8
262```
263
264[apple_streaming_tools]: https://developer.apple.com/documentation/http_live_streaming/about_apple_s_http_live_streaming_tools