-
Notifications
You must be signed in to change notification settings - Fork 0
/
ffprobe_parser.py
77 lines (62 loc) · 2.54 KB
/
ffprobe_parser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import subprocess
import json
import models
class FFProbeCommand(object):
def __init__(self, executable='ffprobe', filename=None, streams='v:0', intervals=None):
interval_param = "-read_intervals {}".format(intervals) if intervals else ""
# TODO - pass parameters to restrict the ffprobe dimensions returned
self._command = \
'"{ffexec}" -hide_banner -loglevel warning -select_streams {streams} {intervals} -show_frames -show_streams -print_format json {filename}' \
.format(ffexec=executable,
filename=filename,
intervals=interval_param,
streams=streams)
print("Executing ffprobe to extract stream and frame information")
print(self._command)
print()
def call(self):
response = subprocess.check_output(self._command, shell=True, stderr=None)
jresponse = json.loads(response)
return FFProbeResponse(jresponse)
# @property
# def filename(self):
# return self._filename
#
# @filename.setter
# def filename(self, new_filename):
# self._filename = new_filename
class FFProbeResponse(object):
def __init__(self, j):
self._json = j
@property
def streams(self):
return self._json['streams']
@property
def frames(self):
return self._json['frames']
# TODO: cater for multiple streams
def get_streams(self):
streams = []
if self._json['streams']:
for idx, jstream in enumerate(self._json['streams']):
stream = models.Stream()
stream.parse_from_json(jstream)
streams.append(stream)
return streams
else:
raise Exception("No streams found in ffprobe response")
# TODO: cater for multiple streams
def get_frames_for_stream(self, stream):
frames = []
if isinstance(stream, models.Stream):
if self._json['frames']:
for idx, jframe in enumerate(self._json['frames']):
if jframe['media_type'] == "video" and jframe['stream_index'] == stream.index:
frame = models.Frame(time_base=stream.time_base, frame_rate=stream.frame_rate, position=idx+1)
frame.parse_from_json(jframe)
frames.append(frame)
return frames
else:
raise Exception("No frames found in ffprobe response")
else:
raise Exception("'stream' argument should be a Stream")