ffmpeg-python
ffmpeg-python copied to clipboard
JSONDecodeError with ffprobe
I am working on a digital photo frame application and ran into the following issue, which is causing me headaches. In my application, I use ffprobe to extract video meta data. When I use the ffmpeg.probe function manually, everything works as expected:
$ python
Python 3.9.2 (default, Feb 28 2021, 17:03:44)
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import ffmpeg
>>> ffmpeg.probe("/mnt/photos/Legacy Photos/Urlaub/Verdon (Mai 2018)/VID_20180528_100301.mp4")['streams']
[{'index': 0, 'codec_name': 'h264', 'codec_long_name': 'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10', 'profile': 'Baseline', 'codec_type': 'video', 'codec_time_base': '267839/16080000', 'codec_tag_string': 'avc1', 'codec_tag': '0x31637661', 'width': 1280, 'height': 720, 'coded_width': 1280, 'coded_height': 720, 'closed_captions': 0, 'has_b_frames': 0, 'sample_aspect_ratio': '1:1', 'display_aspect_ratio': '16:9', 'pix_fmt': 'yuv420p', 'level': 31, 'color_range': 'tv', 'color_space': 'bt709', 'color_transfer': 'bt709', 'color_primaries': 'bt709', 'chroma_location': 'left', 'refs': 1, 'is_avc': 'true', 'nal_length_size': '4', 'r_frame_rate': '30/1', 'avg_frame_rate': '8040000/267839', 'time_base': '1/90000', 'start_pts': 0, 'start_time': '0.000000', 'duration_ts': 1606974, 'duration': '17.855267', 'bit_rate': '9916918', 'bits_per_raw_sample': '8', 'nb_frames': '536', 'disposition': {'default': 1, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0}, 'tags': {'creation_time': '2018-05-28T08:03:23.000000Z', 'language': 'eng', 'handler_name': 'VideoHandle'}}, {'index': 1, 'codec_name': 'aac', 'codec_long_name': 'AAC (Advanced Audio Coding)', 'profile': 'LC', 'codec_type': 'audio', 'codec_time_base': '1/48000', 'codec_tag_string': 'mp4a', 'codec_tag': '0x6134706d', 'sample_fmt': 'fltp', 'sample_rate': '48000', 'channels': 2, 'channel_layout': 'stereo', 'bits_per_sample': 0, 'r_frame_rate': '0/0', 'avg_frame_rate': '0/0', 'time_base': '1/48000', 'start_pts': 0, 'start_time': '0.000000', 'duration_ts': 858111, 'duration': '17.877312', 'bit_rate': '128232', 'max_bit_rate': '128000', 'nb_frames': '838', 'disposition': {'default': 1, 'dub': 0, 'original': 0, 'comment': 0, 'lyrics': 0, 'karaoke': 0, 'forced': 0, 'hearing_impaired': 0, 'visual_impaired': 0, 'clean_effects': 0, 'attached_pic': 0, 'timed_thumbnails': 0}, 'tags': {'creation_time': '2018-05-28T08:03:23.000000Z', 'language': 'eng', 'handler_name': 'SoundHandle'}}]
>>>
If I try to use ffmpeg.probe in my application, I end up with a JSONDecodeError. For testing purposes, I have modified the impacted module to run the very same command as before right at the beginning after import of the ffmpeg module:
""""Module providing repository file class."""
import ffmpeg
ffmpeg.probe("/mnt/photos/Legacy Photos/Urlaub/Verdon (Mai 2018)/VID_20180528_100301.mp4")
When I execute my application and the respective module is imported, it produces the following exception:
Traceback (most recent call last):
File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/home/frame/.local/lib/python3.9/site-packages/pyframe/__main__.py", line 24, in <module>
from .index import run_indexer
File "/home/frame/.local/lib/python3.9/site-packages/pyframe/index/__init__.py", line 8, in <module>
from .indexer import run_indexer
File "/home/frame/.local/lib/python3.9/site-packages/pyframe/index/indexer.py", line 7, in <module>
from repository import ConfigError, Index, Repository
File "/home/frame/.local/lib/python3.9/site-packages/repository/__init__.py", line 17, in <module>
from .file import RepositoryFile
File "/home/frame/.local/lib/python3.9/site-packages/repository/file.py", line 4, in <module>
ffmpeg.probe("/mnt/photos/Legacy Photos/Urlaub/Verdon (Mai 2018)/VID_20180528_100301.mp4")
File "/home/frame/.local/lib/python3.9/site-packages/ffmpeg/_probe.py", line 30, in probe
return json.loads(out2)
File "/usr/lib/python3.9/json/__init__.py", line 346, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.9/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
So, evidently there is something going on with the json decoder. For further testing purposes, I modified the ffprobe function as follows:
...
p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
if p.returncode != 0:
raise Error('ffprobe', out, err)
print(out.decode('utf-8'))
return json.loads(out.decode('utf-8'))
...
And indeed, the json formated meta data is written to standard out before the exception is raised:
{
"streams": [
{
"index": 0,
...
}
}
Means, the file is there, can be accessed and meta data is successfully extracted by the ffprobe application. Unfortunately, I have no clue why the json decoder fails. Possibly, due to interference with some other modules?
Anyone having an idea or suspicion?
I am running Python 3.9.2 under Debian Bullseye on Radxa Zero 3W SBC. The installed version of ffmpeg-python is 0.2.0 (latest version via pip).