From e342f58a050937a0382cb0ce3ac45354b2c3a257 Mon Sep 17 00:00:00 2001 From: Amoh Gyebi Ampofo Date: Fri, 28 Apr 2023 11:30:37 +0000 Subject: [PATCH 1/2] Update __init__.py --- pyffmpeg/__init__.py | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pyffmpeg/__init__.py b/pyffmpeg/__init__.py index ff42c3f..f8cc9fc 100644 --- a/pyffmpeg/__init__.py +++ b/pyffmpeg/__init__.py @@ -139,14 +139,17 @@ def convert(self, input_file, output_file): self._in_duration = float(d) self.monitor(out) - outP = Popen( - options, shell=SHELL, stdin=PIPE, - stdout=PIPE, stderr=PIPE - ) - self._ffmpeg_instances['convert'] = outP - stderr = str(outP.stderr.read(), 'utf-8') - - print(stderr) + try: + outP = Popen( + options, shell=SHELL, stdin=PIPE, + stdout=PIPE, stderr=PIPE + ) + self._ffmpeg_instances['convert'] = outP + stderr = str(outP.stderr.read(), 'utf-8') + + print(stderr) + except: + self.quit() if 'Output #0' not in stderr: lines = stderr.splitlines() @@ -272,9 +275,13 @@ def options(self, opts): if not SHELL: options = shlex.split(options, posix=False) - out = Popen(options, shell=SHELL, stdin=PIPE, stdout=PIPE, stderr=PIPE) - self._ffmpeg_instances['options'] = out - stderr = str(out.stderr.read(), 'utf-8') + try: + out = Popen(options, shell=SHELL, stdin=PIPE, stdout=PIPE, stderr=PIPE) + self._ffmpeg_instances['options'] = out + stderr = str(out.stderr.read(), 'utf-8') + except: + self.quit() + if stderr and 'Output #0' not in stderr: lines = stderr.splitlines() if len(lines) > 0: From 96519625f266e1ee4c353252ca3b7021884f7907 Mon Sep 17 00:00:00 2001 From: kwesi <22204443+yankskwesi@users.noreply.github.com> Date: Tue, 18 Jul 2023 13:56:57 -0400 Subject: [PATCH 2/2] Improving metadata to tag parsing via shared func returning tags check returning to non testing state --- local_probe_t_est.py | 12 +++--- pyffmpeg/pseudo_ffprobe.py | 72 +++++++++++++++-------------------- test_pseudo_ffprobe.py | 77 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 46 deletions(-) diff --git a/local_probe_t_est.py b/local_probe_t_est.py index 5cfa9b5..596612b 100644 --- a/local_probe_t_est.py +++ b/local_probe_t_est.py @@ -1,4 +1,5 @@ import os +import pprint from pyffmpeg import FFprobe @@ -8,15 +9,16 @@ #test_file = "G:\Entertainment\Movies\Interstellar (2014)\Interstellar.2014.720p.BluRay.x264.YIFY.mp4" flv_file = os.path.join(test_folder, 'sample_960x400_ocean_with_audio.flv') -f = FFprobe('flv_file') +f = FFprobe(flv_file) # ret = f.get_album_art('cover.png') -print(f.duration) +pprint.pprint(f.duration) for x in f.metadata: print(x, '\n') -print(f.metadata) -print(f.metadata[0]) +pprint.pprint(f.metadata) +pprint.pprint(f.metadata[0]) # print(f.metadata[0][0]) -print(f.metadata[0][0]['codec']) \ No newline at end of file +print("is codec flv1?") +pprint.pprint(f.metadata[0]['codec'] == 'flv1') \ No newline at end of file diff --git a/pyffmpeg/pseudo_ffprobe.py b/pyffmpeg/pseudo_ffprobe.py index c2513d2..d9a357b 100644 --- a/pyffmpeg/pseudo_ffprobe.py +++ b/pyffmpeg/pseudo_ffprobe.py @@ -9,6 +9,7 @@ import random import os import logging +from collections import defaultdict # from base64 import b64decode from .misc import Paths, SHELL, ModifiedList @@ -116,19 +117,18 @@ def _extract_all(self, stdout): print("Multiple input files found.\ However only one will be probed") all_streams = all_streams[0] - # individual streams streams = all_streams.split('Stream') - for x in range(len(streams)): + self.metadata[-1] = self._parse_input_meta(streams[0]) - if x == 0: - if streams[x]: - self.metadata[-1] = self._parse_input_meta(streams[x]) - else: - if streams[x]: - self.metadata[0].append(self._parse_meta(streams[x])) + tags = defaultdict(list) + for x in range(1, len(streams)): + if streams[x]: + tags.update(self._parse_meta(streams[x])) + + if len(tags) > 0: + self.metadata[0] = tags - # parse other metadata self._parse_other_meta() # then handle stream 0:0 so @@ -165,23 +165,8 @@ def get_album_art(self, out_file=None): def _parse_meta(self, stream): self.logger.info('Inside _parse_meta') - tags = {} metadata = self._strip_meta(stream) - # Previous key will be overriden - prev_key = '' - - for x in range(len(metadata)): - line = metadata[x] - data = line.split(":", 1) - key = data[0].strip() - value = data[1].strip() - # this might be a continuation - if key == '': - tags[prev_key] += "\\r\\n" + data[1].strip() - else: - tags[key] = value - prev_key = key - + tags = self._generate_tags(metadata) return tags def _parse_header(self, line): @@ -202,23 +187,8 @@ def _parse_header(self, line): def _parse_input_meta(self, stream): self.logger.info('Inside _parse_input_meta') - tags = {} metadata = self._strip_input_meta(stream) - - # previous key will be overriden - prev_key = '' - for x in range(len(metadata)): - line = metadata[x] - data = line.split(":", 1) - key = data[0].strip() - value = data[1].strip() - # this might be a continuation - if key == '': - tags[prev_key] += "\\r\\n" + data[1].strip() - else: - tags[key] = value - prev_key = key - + tags = self._generate_tags(metadata) return tags def _parse_other_meta(self): @@ -320,3 +290,23 @@ def _strip_input_meta(self, stdout): meta.append(line) return meta + + def _generate_tags(self, metadata): + prev_key = '' + tags = defaultdict(list) + + for x in range(len(metadata)): + line = metadata[x] + data = line.split(":", 1) + key = data[0].strip() + value = data[1].strip() + # this might be a continuation, if not we add it to orphaned key list + if key == '': + if prev_key == '': + tags['unpaired_values'].append(value) + else: + tags[prev_key].append("\\r\\n" + data[1].strip()) + else: + tags[key] = value + prev_key = key + return tags \ No newline at end of file diff --git a/test_pseudo_ffprobe.py b/test_pseudo_ffprobe.py index 6468895..5b641eb 100644 --- a/test_pseudo_ffprobe.py +++ b/test_pseudo_ffprobe.py @@ -1,6 +1,7 @@ import pytest import os import requests +from collections import defaultdict from pyffmpeg import FFprobe # test speed to make sure no convertion took place @@ -31,3 +32,79 @@ def test_probe(file_name, duration): def test_album_art(): pass + +@pytest.mark.parametrize( + 'file_name', + [ + ("countdown.mp4"), + ] +) +def test_generate_tags(file_name): + metadata_one = [ + ' major_brand : mp42', + ' minor_version : 0', + ' compatible_brands: isommp42', + ' creation_time : 2016-07-05T17:50:46.000000Z', + ' Duration: 00:00:04.37', + 'start: 0.000000', + 'bitrate: 322 kb/s' + ] + metadata_two = [ + 'codec: h264', + 'data_rate: 223 kb/s', + 'dimensions: 640x360', + 'DAR: 16:9', + 'SAR: 1:1', + 'fps: 29.97', + 'tbn: 30k', + 'tbr: 29.97', + ' handler_name : VideoHandler', + ' vendor_id : [0][0][0][0]', + 'codec: aac', + 'bitrate: 96 kb/s', + 'channels: stereo', + 'sample_rate: 44100 Hz', + ' creation_time : 2016-07-05T17:50:46.000000Z', + ' handler_name : IsoMedia File Produced by Google, 5-11-2011', + ' vendor_id : [0][0][0][0]', + 'Parsing a group of options: output url /dev/null.', + 'Opening an output file: /dev/null.', + '[h264 @ 0x7f916e046480] nal_unit_type: 7(SPS), nal_ref_idc: 3', + '[h264 @ 0x7f916e046480] nal_unit_type: 8(PPS), nal_ref_idc: 3' + ] + tags_one = defaultdict(list, + { + 'Duration': '00:00:04.37', + 'bitrate': '322 kb/s', + 'compatible_brands': 'isommp42', + 'creation_time': '2016-07-05T17:50:46.000000Z', + 'major_brand': 'mp42', + 'minor_version': '0', + 'start': '0.000000' + }) + tags_two = defaultdict(list, + { + 'DAR': '16:9', + 'Opening an output file': '/dev/null.', + 'Parsing a group of options': 'output url /dev/null.', + 'SAR': '1:1', + '[h264 @ 0x7f916e046480] nal_unit_type': '8(PPS), nal_ref_idc: ' + '3', + 'bitrate': '96 kb/s', + 'channels': 'stereo', + 'codec': 'aac', + 'creation_time': '2016-07-05T17:50:46.000000Z', + 'data_rate': '223 kb/s', + 'dimensions': '640x360', + 'fps': '29.97', + 'handler_name': 'IsoMedia File Produced by Google, 5-11-2011', + 'sample_rate': '44100 Hz', + 'tbn': '30k', + 'tbr': '29.97', + 'vendor_id': '[0][0][0][0]' + }) + test_file = os.path.join(TEST_FOLDER, file_name) + f = FFprobe(test_file) + + assert tags_one == f._generate_tags(metadata_one) + assert tags_two == f._generate_tags(metadata_two) \ No newline at end of file