diff --git a/.gitignore b/.gitignore index b1efb15..8ef98ae 100644 --- a/.gitignore +++ b/.gitignore @@ -119,3 +119,5 @@ pip-selfcheck.json # Other MANIFEST +*.env +.vscode/* \ No newline at end of file diff --git a/ffprobe/ffprobe.py b/ffprobe/ffprobe.py index 1b00c26..bd86de2 100644 --- a/ffprobe/ffprobe.py +++ b/ffprobe/ffprobe.py @@ -30,14 +30,13 @@ def __init__(self, path_to_video): if os.path.isfile(self.path_to_video) or self.path_to_video.startswith('http'): if platform.system() == 'Windows': - cmd = ["ffprobe", "-show_streams", self.path_to_video] + cmd = ["ffprobe", "-show_streams", "-show_format", self.path_to_video] else: cmd = ["ffprobe -show_streams " + pipes.quote(self.path_to_video)] p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) - stream = False - ignoreLine = False + aggregate_lines = False self.streams = [] self.video = [] self.audio = [] @@ -49,16 +48,19 @@ def __init__(self, path_to_video): line = line.decode('UTF-8', 'ignore') if '[STREAM]' in line: - stream = True - ignoreLine = False + aggregate_lines = True data_lines = [] - elif '[/STREAM]' in line and stream: + elif '[/STREAM]' in line and aggregate_lines: stream = False - ignoreLine = False # noinspection PyUnboundLocalVariable self.streams.append(FFStream(data_lines)) - elif stream: - if '=' in line and ignoreLine == False: + elif '[FORMAT]' in line: + aggregate_lines = True + data_lines = [] + elif '[/FORMAT]' in line and aggregate_lines: + aggregate_lines = False + self.format = FFFormat(data_lines) + elif aggregate_lines and '=' in line: data_lines.append(line) self.metadata = {} @@ -82,12 +84,18 @@ def __init__(self, path_to_video): self.metadata[m.groups()[0]] = m.groups()[1].strip() if '[STREAM]' in line: - stream = True + aggregate_lines = True data_lines = [] elif '[/STREAM]' in line and stream: - stream = False + aggregate_lines = False self.streams.append(FFStream(data_lines)) - elif stream: + elif '[FORMAT]' in line: + aggregate_lines = True + data_lines = [] + elif '[/FORMAT]' in line and aggregate_lines: + aggregate_lines = False + self.format = FFFormat(data_lines) + elif aggregate_lines and '=' in line: data_lines.append(line) if 'timecode' in line: @@ -114,6 +122,14 @@ def __repr__(self): return "".format(**vars(self)) +class FFFormat: + """ + An object representation of the overall container format of a multimedia file. + """ + def __init__(self, data_lines): + for line in data_lines: + self.__dict__.update({key: value for key, value, *_ in [line.strip().split('=')]}) + class FFStream: """ An object representation of an individual stream in a multimedia file. @@ -278,3 +294,13 @@ def bit_rate(self): return int(self.__dict__.get('bit_rate', '')) except ValueError: raise FFProbeError('None integer bit_rate') + + def is_progressive(self): + if self.is_video() and self.__dict__.get('field_order', "") == "progressive": + return True + return False + + def is_interlaced(self): + if self.is_video() and self.__dict__.get('field_order', "") in ["tt", "bb", "tb", "bt"]: + return True + return False diff --git a/tests/ffprobe_test.py b/tests/ffprobe_test.py index 2959376..78d0e8d 100644 --- a/tests/ffprobe_test.py +++ b/tests/ffprobe_test.py @@ -27,8 +27,11 @@ def test_video (): try: if stream.is_video(): frame_rate = stream.frames() / stream.duration_seconds() - print('\t\tFrame Rate:', frame_rate) - print('\t\tFrame Size:', stream.frame_size()) + print('\t\tFrame Rate :', frame_rate) + print('\t\tFrame Size :', stream.frame_size()) + print('\t\tField order:', stream.field_order) + print('\t\tProgressive:', stream.is_progressive()) + print('\t\tInterlaced :', stream.is_interlaced()) print('\t\tDuration:', stream.duration_seconds()) print('\t\tFrames:', stream.frames()) print('\t\tIs video:', stream.is_video()) @@ -38,6 +41,8 @@ def test_video (): print(e) except Exception as e: print(e) + print(f"\tFormat:\n\t\tDuration: {media.format.duration}") + def test_stream (): for test_stream in test_streams: @@ -51,6 +56,9 @@ def test_stream (): frame_rate = stream.frames() / stream.duration_seconds() print('\t\tFrame Rate:', frame_rate) print('\t\tFrame Size:', stream.frame_size()) + print('\t\tField order:', stream.field_order) + print('\t\tProgressive:', stream.is_progressive()) + print('\t\tInterlaced :', stream.is_interlaced()) print('\t\tDuration:', stream.duration_seconds()) print('\t\tFrames:', stream.frames()) print('\t\tIs video:', stream.is_video())