-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmediainfo_linemode.py
85 lines (79 loc) · 4.2 KB
/
mediainfo_linemode.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
76
77
78
79
80
81
82
83
84
85
""" Video information plugin for ranger, requires mediainfo
Install at ~/.config/ranger/plugins
Then you can run it with :lineinfo mediainfo
Or make a keybind for it on the rc.conf, as an example:
map Mv linemode mediainfo
"""
import datetime
import json
import subprocess
import ranger.api
import ranger.core.linemode
@ranger.api.register_linemode
class MyLinemode(ranger.core.linemode.LinemodeBase):
""" ranger linemode class """
name = "mediainfo"
def filetitle(self, fobj, metadata):
return fobj.relative_path
def infostring(self, fobj, metadata):
key_video = key_audio = None
def line_output(dict_key,list_fields):
""" Function that formats the final line , used mostly to prettify the output,
the first argument is the key of the audio/video dictionary from track
so it creates a new one to be easier to extract the data from fields,
the second argument is a list of the fields that we want to show or output
in the line.
"""
output = []
new_dict = dict(json_output["media"]["track"][dict_key])
for value in list_fields:
if value == "Duration":
# Mediainfo duration is in seconds so we convert it to a more readable time.
# The default value is 0 so it doesn't crash if the duration field doesn't
# exist because it's being downloaded.
duration = str(new_dict.get(value,"0"))
converted_time = datetime.timedelta(seconds=round(float(duration)))
output.append(str(converted_time))
continue
if value == "Height":
# Delete the comment of your preferred format (1920x1080 or 1080P)
#output.append("%sx%s" % (new_dict.get("Width"," "),new_dict.get("Height"," ")))
output.append(str(new_dict.get(value," ")) + "P" ) # short,ex: 1080P
continue
if value == "FrameRate":
output.append(str(round(float(new_dict.get(value,"0")))) + "FPS")
continue
output.append(str(new_dict.get(value,"")))
return " ".join(output)
if not fobj.is_directory:
try:
output = subprocess.check_output(['mediainfo','--Output=JSON',fobj.path],
stderr=subprocess.STDOUT).decode("utf-8")
# Prevents the crash if Mediainfo doesn't exist or can't be found
except FileNotFoundError:
raise NotImplementedError
# Not sure if this one is needed, i guess it prevents a crash with other errors
except subprocess.CalledProcessError:
raise NotImplementedError
json_output = json.loads(output)
# Check if the media dictionary is empty, this seems to be needed so it doesn't
# crash if a file has been deleted under this linemode.
if json_output["media"] is None:
raise NotImplementedError
# Finding the keys for the audio and video dictionaries from the larger track dictionary
# so we can make smaller dictionaries to make it easier to extract data from fields.
for key,value in enumerate(json_output["media"]["track"]):
if value["@type"] == "Video":
key_video = key
elif value["@type"] == "Audio":
key_audio = key
# If there's not a video or audio dictionary we don't want to output anything.
if not key_video and not key_audio:
return None
# This is to output for audio files only, someone might find it useful.
if key_audio and not key_video:
return line_output(key_audio,["Format","Duration"])
# List of fields that we want to want to output for video files, the line above
# is the same for audio files, delete the items you don't want or check the
# Mediainfo output to add anymore that you want.
return line_output(key_video,["FrameRate","Format","Height","Duration"])