summaryrefslogtreecommitdiff
path: root/libmat2/video.py
diff options
context:
space:
mode:
authorjvoisin2018-10-28 07:41:04 -0700
committerjvoisin2018-10-28 07:41:04 -0700
commit04bb8c8ccfe1fb789ead340e88b18d6ac9b9e908 (patch)
tree9cecf5f64166001be05838d298ae22b3a5a9ab34 /libmat2/video.py
parent3a070b0ab70c4d4a456bdd12d0cd490ad127e320 (diff)
Add mp4 support
Diffstat (limited to 'libmat2/video.py')
-rw-r--r--libmat2/video.py95
1 files changed, 76 insertions, 19 deletions
diff --git a/libmat2/video.py b/libmat2/video.py
index 85b5b2e..a5029c0 100644
--- a/libmat2/video.py
+++ b/libmat2/video.py
@@ -2,10 +2,37 @@ import os
2import subprocess 2import subprocess
3import logging 3import logging
4 4
5from typing import Dict, Union
6
5from . import exiftool 7from . import exiftool
6 8
7 9
8class AVIParser(exiftool.ExiftoolParser): 10class AbstractFFmpegParser(exiftool.ExiftoolParser):
11 """ Abstract parser for all FFmpeg-based ones, mainly for video. """
12 def remove_all(self) -> bool:
13 cmd = [_get_ffmpeg_path(),
14 '-i', self.filename, # input file
15 '-y', # overwrite existing output file
16 '-map', '0', # copy everything all streams from input to output
17 '-codec', 'copy', # don't decode anything, just copy (speed!)
18 '-loglevel', 'panic', # Don't show log
19 '-hide_banner', # hide the banner
20 '-map_metadata', '-1', # remove supperficial metadata
21 '-map_chapters', '-1', # remove chapters
22 '-disposition', '0', # Remove dispositions (check ffmpeg's manpage)
23 '-fflags', '+bitexact', # don't add any metadata
24 '-flags:v', '+bitexact', # don't add any metadata
25 '-flags:a', '+bitexact', # don't add any metadata
26 self.output_filename]
27 try:
28 subprocess.check_call(cmd)
29 except subprocess.CalledProcessError as e:
30 logging.error("Something went wrong during the processing of %s: %s", self.filename, e)
31 return False
32 return True
33
34
35class AVIParser(AbstractFFmpegParser):
9 mimetypes = {'video/x-msvideo', } 36 mimetypes = {'video/x-msvideo', }
10 meta_whitelist = {'SourceFile', 'ExifToolVersion', 'FileName', 'Directory', 37 meta_whitelist = {'SourceFile', 'ExifToolVersion', 'FileName', 'Directory',
11 'FileSize', 'FileModifyDate', 'FileAccessDate', 38 'FileSize', 'FileModifyDate', 'FileAccessDate',
@@ -24,25 +51,55 @@ class AVIParser(exiftool.ExiftoolParser):
24 'SampleRate', 'AvgBytesPerSec', 'BitsPerSample', 51 'SampleRate', 'AvgBytesPerSec', 'BitsPerSample',
25 'Duration', 'ImageSize', 'Megapixels'} 52 'Duration', 'ImageSize', 'Megapixels'}
26 53
54class MP4Parser(AbstractFFmpegParser):
55 mimetypes = {'video/mp4', }
56 meta_whitelist = {'AudioFormat', 'AvgBitrate', 'Balance', 'TrackDuration',
57 'XResolution', 'YResolution', 'ExifToolVersion',
58 'FileAccessDate', 'FileInodeChangeDate', 'FileModifyDate',
59 'FileName', 'FilePermissions', 'MIMEType', 'FileType',
60 'FileTypeExtension', 'Directory', 'ImageWidth',
61 'ImageSize', 'ImageHeight', 'FileSize', 'SourceFile',
62 'BitDepth', 'Duration', 'AudioChannels',
63 'AudioBitsPerSample', 'AudioSampleRate', 'Megapixels',
64 'MovieDataSize', 'VideoFrameRate', 'MediaTimeScale',
65 'SourceImageHeight', 'SourceImageWidth',
66 'MatrixStructure', 'MediaDuration'}
67 meta_key_value_whitelist = { # some metadata are mandatory :/
68 'CreateDate': '0000:00:00 00:00:00',
69 'CurrentTime': '0 s',
70 'MediaCreateDate': '0000:00:00 00:00:00',
71 'MediaLanguageCode': 'und',
72 'MediaModifyDate': '0000:00:00 00:00:00',
73 'ModifyDate': '0000:00:00 00:00:00',
74 'OpColor': '0 0 0',
75 'PosterTime': '0 s',
76 'PreferredRate': '1',
77 'PreferredVolume': '100.00%',
78 'PreviewDuration': '0 s',
79 'PreviewTime': '0 s',
80 'SelectionDuration': '0 s',
81 'SelectionTime': '0 s',
82 'TrackCreateDate': '0000:00:00 00:00:00',
83 'TrackModifyDate': '0000:00:00 00:00:00',
84 'TrackVolume': '0.00%',
85 }
86
27 def remove_all(self) -> bool: 87 def remove_all(self) -> bool:
28 cmd = [_get_ffmpeg_path(), 88 logging.warning('The format of "%s" (video/mp4) has some mandatory '
29 '-i', self.filename, # input file 89 'metadata fields; mat2 filled them with standard data.',
30 '-y', # overwrite existing output file 90 self.filename)
31 '-loglevel', 'panic', # Don't show log 91 return super().remove_all()
32 '-hide_banner', # hide the banner 92
33 '-codec', 'copy', # don't decode anything, just copy (speed!) 93 def get_meta(self) -> Dict[str, Union[str, dict]]:
34 '-map_metadata', '-1', # remove supperficial metadata 94 meta = super().get_meta()
35 '-map_chapters', '-1', # remove chapters 95
36 '-fflags', '+bitexact', # don't add any metadata 96 ret = dict() # type: Dict[str, Union[str, dict]]
37 '-flags:v', '+bitexact', # don't add any metadata 97 for key, value in meta.items():
38 '-flags:a', '+bitexact', # don't add any metadata 98 if key in self.meta_key_value_whitelist.keys():
39 self.output_filename] 99 if value == self.meta_key_value_whitelist[key]:
40 try: 100 continue
41 subprocess.check_call(cmd) 101 ret[key] = value
42 except subprocess.CalledProcessError as e: 102 return ret
43 logging.error("Something went wrong during the processing of %s: %s", self.filename, e)
44 return False
45 return True
46 103
47 104
48def _get_ffmpeg_path() -> str: # pragma: no cover 105def _get_ffmpeg_path() -> str: # pragma: no cover