From 25bda398c97b9eb25f7128782f94c91a1edd6215 Mon Sep 17 00:00:00 2001
From: Karl Kroening <karlk@kralnet.us>
Date: Sat, 27 Jan 2018 21:19:19 -0800
Subject: [PATCH 1/5] Add ffprobe support

---
 ffmpeg/__init__.py          |  5 +++--
 ffmpeg/_probe.py            | 28 ++++++++++++++++++++++++++++
 ffmpeg/tests/test_ffmpeg.py |  6 ++++++
 3 files changed, 37 insertions(+), 2 deletions(-)
 create mode 100755 ffmpeg/_probe.py

diff --git a/ffmpeg/__init__.py b/ffmpeg/__init__.py
index d4f48d8..7e913d3 100644
--- a/ffmpeg/__init__.py
+++ b/ffmpeg/__init__.py
@@ -1,9 +1,10 @@
 from __future__ import unicode_literals
 
-from . import _filters, _ffmpeg, _run
+from . import _filters, _ffmpeg, _run, _probe
 from ._filters import *
 from ._ffmpeg import *
 from ._run import *
 from ._view import *
+from ._probe import *
 
-__all__ = _filters.__all__ + _ffmpeg.__all__ + _run.__all__ + _view.__all__
+__all__ = _filters.__all__ + _ffmpeg.__all__ + _run.__all__ + _view.__all__ + _probe.__all__
diff --git a/ffmpeg/_probe.py b/ffmpeg/_probe.py
new file mode 100755
index 0000000..300cc89
--- /dev/null
+++ b/ffmpeg/_probe.py
@@ -0,0 +1,28 @@
+import json
+import subprocess
+
+
+class ProbeException(Exception):
+    def __init__(self, stderr_output):
+        super(ProbeException, self).__init__('ffprobe error')
+        self.stderr_output = stderr_output
+
+
+def probe(filename):
+    """Run ffprobe on the specified file and return a JSON representation of the output.
+
+    Raises:
+        ProbeException: if ffprobe returns a non-zero exit code, a ``ProbeException`` is returned with a generic error
+            message.  The stderr output can be retrieved by accessing the ``stderr_output`` property of the exception.
+    """
+    args = ['ffprobe', '-show_format', '-show_streams', '-of', 'json', filename]
+    p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    out, err = p.communicate()
+    if p.returncode != 0:
+        raise ExecException(err)
+    return json.loads(out)
+
+
+__all__ = [
+    'probe',
+]
diff --git a/ffmpeg/tests/test_ffmpeg.py b/ffmpeg/tests/test_ffmpeg.py
index 1380fdb..2650f12 100644
--- a/ffmpeg/tests/test_ffmpeg.py
+++ b/ffmpeg/tests/test_ffmpeg.py
@@ -353,3 +353,9 @@ def test_pipe():
     out_data = p.stdout.read()
     assert len(out_data) == frame_size * (frame_count - start_frame)
     assert out_data == in_data[start_frame*frame_size:]
+
+
+def test_ffprobe():
+    data = ffmpeg.probe(TEST_INPUT_FILE1)
+    assert set(data.keys()) == {'format', 'streams'}
+    assert data['format']['duration'] == '7.036000'
-- 
GitLab


From 24e737f78e068cd81a925b7e1df940b72bb74b07 Mon Sep 17 00:00:00 2001
From: Karl Kroening <karlk@kralnet.us>
Date: Sat, 27 Jan 2018 21:32:11 -0800
Subject: [PATCH 2/5] Fix ffprobe string decoding

---
 ffmpeg/_probe.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ffmpeg/_probe.py b/ffmpeg/_probe.py
index 300cc89..0287939 100755
--- a/ffmpeg/_probe.py
+++ b/ffmpeg/_probe.py
@@ -20,7 +20,7 @@ def probe(filename):
     out, err = p.communicate()
     if p.returncode != 0:
         raise ExecException(err)
-    return json.loads(out)
+    return json.loads(out.decode('utf-8'))
 
 
 __all__ = [
-- 
GitLab


From 2fff94af6c61530230d27c1a2e84ac1f1bc07c0c Mon Sep 17 00:00:00 2001
From: Karl Kroening <karlk@kralnet.us>
Date: Sat, 27 Jan 2018 22:51:05 -0800
Subject: [PATCH 3/5] Fix probe exception handling and add test

---
 ffmpeg/_probe.py            | 3 ++-
 ffmpeg/tests/test_ffmpeg.py | 8 ++++++++
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/ffmpeg/_probe.py b/ffmpeg/_probe.py
index 0287939..ea3a52c 100755
--- a/ffmpeg/_probe.py
+++ b/ffmpeg/_probe.py
@@ -19,10 +19,11 @@ def probe(filename):
     p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     out, err = p.communicate()
     if p.returncode != 0:
-        raise ExecException(err)
+        raise ProbeException(err)
     return json.loads(out.decode('utf-8'))
 
 
 __all__ = [
     'probe',
+    'ProbeException',
 ]
diff --git a/ffmpeg/tests/test_ffmpeg.py b/ffmpeg/tests/test_ffmpeg.py
index 2650f12..07c5c4b 100644
--- a/ffmpeg/tests/test_ffmpeg.py
+++ b/ffmpeg/tests/test_ffmpeg.py
@@ -16,6 +16,7 @@ TEST_INPUT_FILE1 = os.path.join(SAMPLE_DATA_DIR, 'in1.mp4')
 TEST_OVERLAY_FILE = os.path.join(SAMPLE_DATA_DIR, 'overlay.png')
 TEST_OUTPUT_FILE1 = os.path.join(SAMPLE_DATA_DIR, 'out1.mp4')
 TEST_OUTPUT_FILE2 = os.path.join(SAMPLE_DATA_DIR, 'out2.mp4')
+BOGUS_INPUT_FILE = os.path.join(SAMPLE_DATA_DIR, 'bogus')
 
 
 subprocess.check_call(['ffmpeg', '-version'])
@@ -359,3 +360,10 @@ def test_ffprobe():
     data = ffmpeg.probe(TEST_INPUT_FILE1)
     assert set(data.keys()) == {'format', 'streams'}
     assert data['format']['duration'] == '7.036000'
+
+
+def test_ffprobe_exception():
+    with pytest.raises(ffmpeg.ProbeException) as excinfo:
+        ffmpeg.probe(BOGUS_INPUT_FILE)
+    assert excinfo.value.message == 'ffprobe error'
+    assert 'No such file or directory' in excinfo.value.stderr_output
-- 
GitLab


From 87a168a063323555665c239c539f4dec52e6c95a Mon Sep 17 00:00:00 2001
From: Davide Depau <davide@depau.eu>
Date: Thu, 8 Mar 2018 22:52:06 +0100
Subject: [PATCH 4/5] Do not use Exception.message, use str(Exception) instead

---
 ffmpeg/tests/test_ffmpeg.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ffmpeg/tests/test_ffmpeg.py b/ffmpeg/tests/test_ffmpeg.py
index 07c5c4b..ad32784 100644
--- a/ffmpeg/tests/test_ffmpeg.py
+++ b/ffmpeg/tests/test_ffmpeg.py
@@ -365,5 +365,5 @@ def test_ffprobe():
 def test_ffprobe_exception():
     with pytest.raises(ffmpeg.ProbeException) as excinfo:
         ffmpeg.probe(BOGUS_INPUT_FILE)
-    assert excinfo.value.message == 'ffprobe error'
+    assert str(excinfo.value) == 'ffprobe error'
     assert 'No such file or directory' in excinfo.value.stderr_output
-- 
GitLab


From 4927bbeea9037145c21a85df71c1d83c63a7274f Mon Sep 17 00:00:00 2001
From: Davide Depau <davide@depau.eu>
Date: Thu, 8 Mar 2018 23:02:04 +0100
Subject: [PATCH 5/5] Fix string type inconsistency error in ffprobe test

---
 ffmpeg/tests/test_ffmpeg.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ffmpeg/tests/test_ffmpeg.py b/ffmpeg/tests/test_ffmpeg.py
index ad32784..b874a86 100644
--- a/ffmpeg/tests/test_ffmpeg.py
+++ b/ffmpeg/tests/test_ffmpeg.py
@@ -366,4 +366,4 @@ def test_ffprobe_exception():
     with pytest.raises(ffmpeg.ProbeException) as excinfo:
         ffmpeg.probe(BOGUS_INPUT_FILE)
     assert str(excinfo.value) == 'ffprobe error'
-    assert 'No such file or directory' in excinfo.value.stderr_output
+    assert b'No such file or directory' in excinfo.value.stderr_output
-- 
GitLab