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 ?
[…] It solves 95% of my usage scenarios. To find out how to use the code, see the article https://fio.ie/python-column-provider-nautilus/ […]