Skip to content

Commit d022dd7

Browse files
authored
Update README.md
1 parent 855a7a2 commit d022dd7

File tree

1 file changed

+250
-1
lines changed

1 file changed

+250
-1
lines changed

README.md

+250-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ several options for controlling its behavior. The `Container` may be in an
153153
inconsistent state after calling `rearrange()` if its contents violate the
154154
Matroska specification in some way (e.g. if it has an impermissible child).
155155

156-
The `Segment` Element is more intelligent in its `rearrange()` method. It generates
156+
The `Segment` Element has a more intelligent `normalize()` method. It generates
157157
a `SeekHead` element at the beginning of the file with links to its children. It
158158
tries to move the more important children before the `Clusters`, and moves the
159159
rest to the end of the file. Its requirements for consistency are also a bit
@@ -174,3 +174,252 @@ The output may span multiple lines, although it is not terminated by a newline.
174174
to a specified recursion depth) and concatenates them with indentation in a
175175
newline-terminated string. The latter returns a newline-terminated table
176176
summarizing which child (and descendent) elements occupy which blocks of space.
177+
178+
## Example
179+
180+
Load a Matroska file:
181+
```python
182+
from ebml.container import File
183+
ebml_file = File('The_Blues_Brothers.mkv')
184+
```
185+
186+
Output:
187+
```
188+
INFO:ebml.container:Read summary in 0.084 seconds
189+
```
190+
191+
```python
192+
print(ebml_file.summary())
193+
```
194+
195+
Output:
196+
```
197+
File: stream=<_io.BufferedReader name='The_Blues_Brothers.mkv'>, size=27147770837, 2 children
198+
ElementSegment Segment (12+27147770785 @40): 11 children
199+
Segment UID: CE:C4:57:4C:E0:1E:AD:7C:14:D7:2C:84:44:B4:8E:50
200+
Title: 'The Blues Brothers'
201+
Duration: 8866.94 seconds
202+
Time scale: 1000000 nanoseconds
203+
Muxing app: 'libmakemkv v1.8.9 (1.3.0/1.4.1) x86_64-linux-gnu'
204+
Writing app: 'MakeMKV v1.8.9 linux(x64-release)'
205+
Seek entries:
206+
Chapters: 1907
207+
Cues: 27147145828
208+
Info: 2944
209+
Tags: 27147331697
210+
Attachments: 27147336885
211+
Tracks: 1292
212+
Attachments:
213+
ElementAttachedFile: 'myth_metadata.xml' (application/xml), 21232 bytes: 'Master XML metadata'
214+
UID: 34:4B:C9:07:67:3D:6B:E5
215+
ElementAttachedFile: 'cover.jpg' (image/jpeg), 200376 bytes: 'Cover image'
216+
UID: 7C:F7:FC:C9:FF:1F:F1:AD
217+
ElementAttachedFile: 'fanart.jpg' (image/jpeg), 212080 bytes: 'Fan art image'
218+
UID: E9:EF:E2:31:8C:12:E3:49
219+
Tracks:
220+
ElementTrackEntry: video lang=eng codec=V_MPEG4/ISO/AVC num=1 uid=1
221+
Flags: enabled default !forced !lacing
222+
ElementVideo: dims=1920x1080, display=1920x1080, aspect='free resizing'
223+
Stereo: mono
224+
Interlaced: False
225+
ElementTrackEntry: audio lang=eng codec=A_DTS num=2 uid=2: 'Surround 5.1'
226+
Flags: enabled default !forced lacing
227+
ElementAudio: channels=6 sampling=48k
228+
ElementTrackEntry: audio lang=fra codec=A_DTS num=3 uid=3: 'Stereo'
229+
Flags: enabled !default !forced lacing
230+
ElementAudio: channels=2 sampling=48k
231+
ElementTrackEntry: subtitle lang=eng codec=S_HDMV/PGS num=4 uid=4
232+
Flags: enabled default !forced !lacing
233+
ElementTrackEntry: subtitle lang=spa codec=S_HDMV/PGS num=6 uid=6
234+
Flags: enabled !default !forced !lacing
235+
ElementTrackEntry: subtitle lang=fra codec=S_HDMV/PGS num=8 uid=8
236+
Flags: enabled !default !forced !lacing
237+
ElementTrackEntry: subtitle lang=fra codec=S_HDMV/PGS num=10 uid=10
238+
Flags: enabled !default forced !lacing
239+
Tags:
240+
ElementTag: MOVIE (50), 67 tags
241+
ElementSimpleTag lang=eng def=True: 'TITLE' => 'The Blues Brothers'
242+
ElementSimpleTag lang=eng def=True: 'DIRECTOR' => 'John Landis'
243+
ElementSimpleTag lang=eng def=True: 'GENRE' => 'Comedy'
244+
ElementSimpleTag lang=eng def=True: 'ACTOR' => 'Dan Aykroyd'
245+
ElementSimpleTag lang=eng def=True: 'CHARACTER' => 'Elwood Blues (as Elwood)'
246+
ElementSimpleTag lang=eng def=True: 'ACTOR' => 'John Belushi'
247+
ElementSimpleTag lang=eng def=True: 'CHARACTER' => "'Joliet' Jake Blues (as Jake)"
248+
...
249+
```
250+
251+
Get the main segment of the file:
252+
```python
253+
segment = next(ebml_file.children_named('Segment'))
254+
segment
255+
```
256+
257+
Output (`__repr__()` version):
258+
```
259+
<ElementSegment [18:53:80:67] 'Segment' size=12+27147770785 @40>
260+
```
261+
262+
```python
263+
str(segment)
264+
```
265+
266+
output (`__str__()` version):
267+
```
268+
'ElementSegment Segment (12+27147770785 @40): 11 children'
269+
```
270+
271+
Add an attached file with the `Segment.add_attachment()` convenience function.
272+
```python
273+
with open('banner.jpg', 'rb') as f:
274+
banner_contents = f.read()
275+
attachment = segment.add_attachment('banner.jpg', 'image/jpeg', 'Banner image')
276+
attachment.file_data = banner_contents
277+
attachment.summary()
278+
```
279+
280+
Output:
281+
```
282+
"ElementAttachedFile: 'banner.jpg' (image/jpeg), 104464 bytes: 'Banner image'\n UID: 07:10:12:34:11:A3:F1:43"
283+
```
284+
285+
```python
286+
print(ebml_file.summary())
287+
```
288+
289+
Output (note that it lists the new attachment):
290+
```
291+
File: stream=<_io.BufferedReader name='The_Blues_Brothers.mkv'>, size=27147770837, 2 children
292+
ElementSegment Segment (12+27147770785 @40): 11 children
293+
Segment UID: CE:C4:57:4C:E0:1E:AD:7C:14:D7:2C:84:44:B4:8E:50
294+
Title: 'The Blues Brothers'
295+
Duration: 8866.94 seconds
296+
Time scale: 1000000 nanoseconds
297+
Muxing app: 'libmakemkv v1.8.9 (1.3.0/1.4.1) x86_64-linux-gnu'
298+
Writing app: 'MakeMKV v1.8.9 linux(x64-release)'
299+
Seek entries:
300+
Chapters: 1907
301+
Cues: 27147145828
302+
Info: 2944
303+
Tags: 27147331697
304+
Attachments: 27147336885
305+
Tracks: 1292
306+
Attachments:
307+
ElementAttachedFile: 'myth_metadata.xml' (application/xml), 21232 bytes: 'Master XML metadata'
308+
UID: 34:4B:C9:07:67:3D:6B:E5
309+
ElementAttachedFile: 'cover.jpg' (image/jpeg), 200376 bytes: 'Cover image'
310+
UID: 7C:F7:FC:C9:FF:1F:F1:AD
311+
ElementAttachedFile: 'fanart.jpg' (image/jpeg), 212080 bytes: 'Fan art image'
312+
UID: E9:EF:E2:31:8C:12:E3:49
313+
ElementAttachedFile: 'banner.jpg' (image/jpeg), 104464 bytes: 'Banner image'
314+
UID: 07:10:12:34:11:A3:F1:43
315+
Tracks:
316+
ElementTrackEntry: video lang=eng codec=V_MPEG4/ISO/AVC num=1 uid=1
317+
Flags: enabled default !forced !lacing
318+
ElementVideo: dims=1920x1080, display=1920x1080, aspect='free resizing'
319+
Stereo: mono
320+
Interlaced: False
321+
ElementTrackEntry: audio lang=eng codec=A_DTS num=2 uid=2: 'Surround 5.1'
322+
Flags: enabled default !forced lacing
323+
ElementAudio: channels=6 sampling=48k
324+
ElementTrackEntry: audio lang=fra codec=A_DTS num=3 uid=3: 'Stereo'
325+
Flags: enabled !default !forced lacing
326+
ElementAudio: channels=2 sampling=48k
327+
ElementTrackEntry: subtitle lang=eng codec=S_HDMV/PGS num=4 uid=4
328+
Flags: enabled default !forced !lacing
329+
ElementTrackEntry: subtitle lang=spa codec=S_HDMV/PGS num=6 uid=6
330+
Flags: enabled !default !forced !lacing
331+
ElementTrackEntry: subtitle lang=fra codec=S_HDMV/PGS num=8 uid=8
332+
Flags: enabled !default !forced !lacing
333+
ElementTrackEntry: subtitle lang=fra codec=S_HDMV/PGS num=10 uid=10
334+
Flags: enabled !default forced !lacing
335+
Tags:
336+
ElementTag: MOVIE (50), 67 tags
337+
ElementSimpleTag lang=eng def=True: 'TITLE' => 'The Blues Brothers'
338+
ElementSimpleTag lang=eng def=True: 'DIRECTOR' => 'John Landis'
339+
ElementSimpleTag lang=eng def=True: 'GENRE' => 'Comedy'
340+
ElementSimpleTag lang=eng def=True: 'ACTOR' => 'Dan Aykroyd'
341+
ElementSimpleTag lang=eng def=True: 'CHARACTER' => 'Elwood Blues (as Elwood)'
342+
ElementSimpleTag lang=eng def=True: 'ACTOR' => 'John Belushi'
343+
ElementSimpleTag lang=eng def=True: 'CHARACTER' => "'Joliet' Jake Blues (as Jake)"
344+
...
345+
```
346+
347+
Where did the attachment go? Here's how the segment tracks its space:
348+
```python
349+
print(segment.print_space())
350+
```
351+
352+
Output:
353+
```
354+
1> 0 --131 | 0 --131 | 131 bytes: [ 0] SeekHead
355+
1> 131 --1292 | 131 --1292 | 1161 bytes: [ 1] Void
356+
1> 1292 --1877 | 1292 --1877 | 585 bytes: [ 2] Tracks
357+
1> 1877 --1907 | 1877 --1907 | 30 bytes: [ 3] Void
358+
1> 1907 --2944 | 1907 --2944 | 1037 bytes: [ 4] Chapters
359+
1> 2944 --3102 | 2944 --3102 | 158 bytes: [ 5] Info
360+
1> 3102 --3968 | 3102 --3968 | 866 bytes: [ 6] Void
361+
1> 3968 --27147145828 | 3968 --27147145828 | 27147141860 bytes: ***NO CHILD***
362+
1> 27147145828--27147331697 | 27147145828--27147331697 | 185869 bytes: [ 7] Cues
363+
1> 27147331697--27147336787 | 27147331697--27147336787 | 5090 bytes: [ 8] Tags
364+
1> 27147336787--27147336885 | 27147336787--27147336885 | 98 bytes: [ 9] Void
365+
1> 27147336885--27147770785 | 27147336885--27147770785 | 433900 bytes: [10] Attachments
366+
```
367+
368+
As far as the segment knows, it's still in a consistent state, because attachments are
369+
actually grandchildren of the Segment.
370+
```python
371+
attachments = next(segment.children_named('Attachments'))
372+
print(attachments.print_space())
373+
```
374+
375+
Output: you can see that it still only has 6 bytes allocated to the new attached file.
376+
```
377+
1> 0 --21313 | 0 --21313 | 21313 bytes: [ 0] AttachedFile
378+
1> 21313 --221749 | 21313 --221749 | 200436 bytes: [ 1] AttachedFile
379+
1> 221749 --433893 | 221749 --433893 | 212144 bytes: [ 2] AttachedFile
380+
1> 433893 --433899 | 433893 --433899 | 6 bytes: [ 3] AttachedFile
381+
1> 433893 --433899 | 433893 --433899 | 6 bytes: ***OVERFLOW***
382+
```
383+
384+
The call to `segment.normalize()` is the most intellegent, catch-all method for
385+
recursively rearranging an mkv file without moving Cues or Clusters (i.e. the parts
386+
that take up 99% of the file). Of course, in this case it doesn't have to work very
387+
hard since the attachments are already at the end of the file.
388+
```python
389+
segment.normalize()
390+
print(segment.print_space())
391+
```
392+
393+
Output: note that Attachments has grown.
394+
```
395+
1> 0 --131 | 0 --131 | 131 bytes: [ 0] SeekHead
396+
1> 131 --1292 | 131 --1292 | 1161 bytes: [ 1] Void
397+
1> 1292 --1877 | 1292 --1877 | 585 bytes: [ 2] Tracks
398+
1> 1877 --1907 | 1877 --1907 | 30 bytes: [ 3] Void
399+
1> 1907 --2944 | 1907 --2944 | 1037 bytes: [ 4] Chapters
400+
1> 2944 --3102 | 2944 --3102 | 158 bytes: [ 5] Info
401+
1> 3102 --3968 | 3102 --3968 | 866 bytes: [ 6] Void
402+
1> 3968 --27147145828 | 3968 --27147145828 | 27147141860 bytes: ***NO CHILD***
403+
1> 27147145828--27147331697 | 27147145828--27147331697 | 185869 bytes: [ 7] Cues
404+
1> 27147331697--27147336787 | 27147331697--27147336787 | 5090 bytes: [ 8] Tags
405+
1> 27147336787--27147336885 | 27147336787--27147336885 | 98 bytes: [ 9] Void
406+
1> 27147336885--27147875312 | 27147336885--27147875312 | 538427 bytes: [10] Attachments
407+
```
408+
409+
```python
410+
print(attachments.print_space())
411+
```
412+
413+
Output: now there's enough space for the attached file.
414+
```
415+
1> 0 --21313 | 0 --21313 | 21313 bytes: [ 0] AttachedFile
416+
1> 21313 --221749 | 21313 --221749 | 200436 bytes: [ 1] AttachedFile
417+
1> 221749 --433893 | 221749 --433893 | 212144 bytes: [ 2] AttachedFile
418+
1> 433893 --538420 | 433893 --538420 | 104527 bytes: [ 3] AttachedFile
419+
```
420+
421+
Save the changes to the file:
422+
```python
423+
with open('/dev/null', 'wb') as f:
424+
ebml_file.save_changes(f)
425+
```

0 commit comments

Comments
 (0)