Below is an example of a python column provider for nautilus.
Identifying poor quality video files 480p, 720p … is difficult in nautilus at a glance.
You need to open the file properties to view the video metadata.
While there are a number of extensions out there for EXIF etc, i decided to implement my own.
Originally i tried to use MediaInfo, but it was far too slow. This is what i ended up with.
To activate it, just login and logout, or kill nautilus and restart it.
Create target directory and file
mkdir -vp ~/.local/share/nautilus-python/extensions
touch ~/.local/share/nautilus-python/extensions/VideoMetaData.py
Install python libraries
pip install hachoir-metadata
pip install hachoir-parser
pip install hachoir-core
Add this to ~/.local/share/nautilus-python/extensions/VideoMetaData.py
#!/usr/bin/python
# dave@fio.ie
import os
import urllib
import logging
import re
import gi
gi.require_version('Nautilus', '3.0')
gi.require_version('Gtk', '3.0')
from gi.repository import Nautilus, GObject, Gtk, Gdk, GdkPixbuf
from hachoir_core.error import HachoirError
from hachoir_core.stream import InputIOStream
from hachoir_parser import guessParser
from hachoir_metadata import extractMetadata
class VideoMetadataExtension(GObject.GObject, Nautilus.ColumnProvider, Nautilus.MenuProvider, Nautilus.InfoProvider):
def __init__(self):
logging.basicConfig(filename='/tmp/VideoMetadataExtension.log',level=logging.DEBUG)
pass
def get_columns(self):
return (
Nautilus.Column(name="NautilusPython::video_width_columnn",attribute="video_width",label="Width",description="Video width"),
Nautilus.Column(name="NautilusPython::video_height_columnn",attribute="video_height",label="Height",description="Video height"),
)
def update_file_info_full(self, provider, handle, closure, file_info):
filename = urllib.unquote(file_info.get_uri()[7:])
video_width = ''
video_height = ''
name_suggestion = ''
file_info.add_string_attribute('video_width', video_width)
file_info.add_string_attribute('video_height', video_height)
file_info.add_string_attribute('name_suggestion', name_suggestion)
if file_info.get_uri_scheme() != 'file':
logging.debug("Skipped: " + filename)
return Nautilus.OperationResult.COMPLETE
videomimes = [
'video/x-msvideo',
'video/mpeg',
'video/x-ms-wmv',
'video/mp4',
'video/x-flv',
'video/x-matroska'
]
for mime in videomimes:
if file_info.is_mime_type(mime):
GObject.idle_add(self.get_video_metadata, provider, handle, closure, file_info)
logging.debug("in Progress: " + filename)
return Nautilus.OperationResult.IN_PROGRESS
logging.debug("Skipped: " + filename)
return Nautilus.OperationResult.COMPLETE
def get_video_metadata(self, provider, handle, closure, file_info):
video_width = ''
video_height = ''
name_suggestion = ''
filename = urllib.unquote(file_info.get_uri()[7:])
filelike = open(filename, "rw+")
try:
filelike.seek(0)
except (AttributeError, IOError):
logging.debug("Unabled to read: " + filename)
Nautilus.info_provider_update_complete_invoke(closure, provider, handle, Nautilus.OperationResult.FAILED)
return False
stream = InputIOStream(filelike, None, tags=[])
parser = guessParser(stream)
if not parser:
logging.debug("Unabled to determine parser: " + filename)
Nautilus.info_provider_update_complete_invoke(closure, provider, handle, Nautilus.OperationResult.FAILED)
return False
try:
metadata = extractMetadata(parser)
except HachoirError:
logging.debug("Unabled to extract metadata: " + filename)
Nautilus.info_provider_update_complete_invoke(closure, provider, handle, Nautilus.OperationResult.FAILED)
return False
if metadata is None:
logging.debug("Metadata None: " + filename)
Nautilus.info_provider_update_complete_invoke(closure, provider, handle, Nautilus.OperationResult.FAILED)
return False
matchObj = re.search( r'Image width: (.*?) pixels', str(metadata), re.M|re.I)
if matchObj:
video_width = matchObj.group(1)
matchObj = re.search( r'Image height: (.*?) pixels', str(metadata), re.M|re.I)
if matchObj:
video_height = matchObj.group(1)
file_info.add_string_attribute('video_width', video_width)
file_info.add_string_attribute('video_height', video_height)
file_info.add_string_attribute('name_suggestion', name_suggestion)
logging.debug("Completed: " + filename)
file_info.invalidate_extension_info()
Nautilus.info_provider_update_complete_invoke(closure, provider, handle, Nautilus.OperationResult.COMPLETE)
return False
In detailed list view, have you managed to sort the rows according to the value of the new columns?
sorry for the slow reply.. i have looked into this yet.. its on my todo!
hi, did you manage to sort the new columns ? i’m trying to do it but I don’t know how ?