gbstack / ffprobe-python

A wrapper of ffprobe command to extract metadata from media files.
Other
59 stars 56 forks source link

ValueError: not enough values to unpack #19

Open yagarea opened 2 years ago

yagarea commented 2 years ago

Hello, I am trying to use this plugin but when I use it I get this error:

Traceback (most recent call last): File "/home/john/Projects/autotranscoder/./transcoder.py", line 12, in FFProbe(file) File "/home/john/.local/lib/python3.9/site-packages/ffprobe/ffprobe.py", line 54, in init self.streams.append(FFStream(datalines)) File "/home/john/.local/lib/python3.9/site-packages/ffprobe/ffprobe.py", line 114, in init self.dict.update({key: value for key, value, * in [line.strip().split('=')]}) File "/home/john/.local/lib/python3.9/site-packages/ffprobe/ffprobe.py", line 114, in self.dict.update({key: value for key, value, *_ in [line.strip().split('=')]}) ValueError: not enough values to unpack (expected at least 2, got 1)

This is my code

#!/usr/bin/env python

from ffprobe import FFProbe
import os

path = "/home/videos/"

for files in os.listdir(path):
    file = os.path.join(path, files)
    if os.path.isfile(file):
        FFProbe(file)
        print(metadata)

I am 100% sure that directory exists and for loop generates valid paths to video files.

How can I fix it ?

yipjustin commented 2 years ago

I encountered the same issue. The problem is the code assumes all information within the "stream" tag are one liner of the form <KEY>=<VALUE>.

But ffprobe may return multi-line <VALUE>. For example, my ffprobe output is like:

[STREAM]
index=0
codec_name=h264
codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
profile=High
codec_type=video
codec_time_base=929999/44640000
codec_tag_string=avc1
codec_tag=0x31637661
width=1080
height=1080
coded_width=1088
coded_height=1088
closed_captions=0
has_b_frames=0
sample_aspect_ratio=1:1
display_aspect_ratio=1:1
pix_fmt=yuvj420p
level=32
color_range=pc
color_space=bt470bg
color_transfer=smpte170m
color_primaries=bt470bg
chroma_location=left
field_order=unknown
timecode=N/A
refs=1
is_avc=true
nal_length_size=4
id=N/A
r_frame_rate=24/1
avg_frame_rate=22320000/929999
time_base=1/90000
start_pts=0
start_time=0.000000
duration_ts=929999
duration=10.333322
bit_rate=12313617
max_bit_rate=N/A
bits_per_raw_sample=8
nb_frames=248
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:rotate=90
TAG:creation_time=2022-04-01T02:28:17.000000Z
TAG:language=eng
TAG:handler_name=VideoHandle
[SIDE_DATA]
side_data_type=Display Matrix
displaymatrix=
00000000:            0       65536           0
00000001:       -65536           0           0
00000002:            0           0  1073741824

rotation=-90
[/SIDE_DATA]
[/STREAM]

There are sub-fields [SIDE_DATA] and multi-line field like displaymatrix that messes up the parsing logic.

erat-verbum commented 2 years ago

I have addressed this issue by simply ignoring multi-line data in my fork https://github.com/erat-verbum/ffprobe-python

Feel free to use it.

jboy commented 1 year ago

If anyone's looking for a longer-term solution, I've switched to a ffprobe -print_format json command-line that should handle multi-line data without any problems (because it's all JSON, so it doesn't need to be parsed line-by-line), plus a bunch of other bug-fixes, features, and improvements, in a fork: https://github.com/jboy/ffprobe3-python3

(Python3 only, sorry.)