1

I have a folder with some 300 videos. I want to sort these by their video bitrate. I use a command 'mediainfo' to obtain the bitrate info of a file . Is it possible to write a script (possibly in python) to sort these videos using this command . I dont know much about scripts, so please do explain :) .Thanks in advance.

3
  • is it a "flat" directory or you need it to be recursively? Oct 12, 2014 at 8:33
  • By flat, do you mean whether there are directories inside it?If so,no.there are no directories inside the directory
    – Akheel K M
    Oct 12, 2014 at 9:17
  • Thanks, I have to run, will get back to it later if it is still "open" by then. BTW the mediainfo command is quite slow :) Oct 12, 2014 at 9:39

4 Answers 4

1

I quickly made a python script which calls mediainfo process for each file in a search criteria and sorts then by sorting criteria and prints out the results. Modify for your own needs.

This uses pure string sorting for the values. You could also add reverse=True for sorted method if wanted or do whatever you want with the code otherwise. This script requires you to pass arguments with ' around them. Sort criteria argument can be any value that mediainfo returns from the files.

import os, sys, glob
import pprint

# Call: python mediainfo_sort.py 'search_criteria' 'sort_criteria'
# Call example: python mediainfo_sort.py '*.avi' 'Bit rate'

files = glob.glob(sys.argv[1])
criteria = sys.argv[2]

# Will have data in format: {'file_path': {'Media Attribute', 'Value'}}
file_datas = {}

# Contruct data by calling mediainfo for all files in 
for file_path in files:
    mediainfo = os.popen('mediainfo "%s"' % file_path).read()
    file_data = {}
    infos = mediainfo.splitlines()
    for info in infos:
        if ':' in info:
            info_split = info.split(':')
            file_data[info_split[0].strip()] = info_split[1].strip()
        file_datas[file_path] = file_data

# function for sorted, uses Media attribute (sort_criteria) value as sorting key
def getKey(item):
    return item[1][criteria]

sorted_files = sorted(file_datas.items(), key=getKey)

# In the end just join the keys (filenames) with newline and print
print '\n'.join([x[0] for x in sorted_files])
2
  • It works almost perfect except for when there are whitespaces in the filenames. I dont know why but those with spaces in their name doesnt get their data stored.
    – Akheel K M
    Oct 12, 2014 at 17:20
  • Sorry, my bad. I just modified the code to include quotes around %s, like so: mediainfo = os.popen('mediainfo "%s"' % file_path).read() which corrects the problem. Eventually this code isn't actually written to be failsafe and it should use subprocess module instead of popen and catch the possible errors. Consider the code as a starting point. You talked about a python script using mediainfo for sorting files and that is the only thing I did, the rest is up to further development by you or anyone. :)
    – Ahti Komu
    Oct 13, 2014 at 6:20
1

You may find it helpful to check out this thread.

Here's a quick summary as suggested in the comments:

1) install python-nautilus and python-mutagen with sudo apt-get install python-nautilus python-mutagen

2) Set your PYTHONPATH variable by following the instructions here.

3) Create a directory called python-extensions in ~/.nautilus

4) Download this python script and paste it into ~/.nautilus/python-extensions

5) Restart nautilus with $ nautilus -q && nautilus &

I still recommend reading through the thread though, there is a lot of useful information there.

1
  • This if I could have gotten to work wouldve been the easiest solution.But some problem somewhere that I cant figure out
    – Akheel K M
    Oct 12, 2014 at 17:24
1

Like I mentioned in my comment, the mediainfo command is really, really slow. There are better alternatives I think.

Having said that, here is my version of a python script, that should do the job (python3):

#!/usr/bin/env python3

import os
import subprocess

directory = "/path/to/files"

# list the files in the directory
files_tosort = os.listdir(directory)

filedata = []
for file in files_tosort:
    # combine filepath and file, take care of the whitespaces
    filepath = directory+"/"+file; command = "mediainfo "+"'"+filepath+"'"
    # get the file's data
    data = subprocess.check_output(["/bin/bash", "-c", command]).decode("utf-8")
    # extract the bitrate from the output
    bitrate = [line[line.find(":")+2:].replace("Kbps", "").replace(" ", "") \
               for line in data.splitlines() if "Bit rate" in line][0]
    # add the found bitrate+filename to he list
    filedata.append((int(bitrate), file))

# sort the list by the bitrate
filedata.sort(key=lambda item: item[0])
# print out
for item in filedata:
    print("bitrate: "+str(item[0])+" Kbps\t file: "+item[1])

It creates an output, looking like:

bitrate: 606 Kbps    file: film1.avi
bitrate: 731 Kbps    file: film10.avi
bitrate: 790 Kbps    file: film4.avi
bitrate: 802 Kbps    file: film3.avi
bitrate: 845 Kbps    file: film6.avi
bitrate: 919 Kbps    file: film7.avi
bitrate: 984 Kbps    file: film5.avi
bitrate: 1023 Kbps   file: film2.avi
bitrate: 1088 Kbps   file: film8.avi

Note:

if there is a risk of unreadable files, a "try / except" should be built into the script, to pass in those cases.

How to use:

Like with any script, copy the script into an empty file, set the path to the files in the head of the script, save it as sort_video.py and run it by the command:

python3 /path/to/sort_video.py
0

Using command mediainfo and sort I'm able to sort about 100+ videos in less than 10s:

mediainfo --Inform="General;%OverallBitRate% | %CompleteName% (%OverallBitRate/String%)\n" * | sort -n

However, it sorts videos by the global video file bit rate and not only by the video stream bit rate.

Sample output

1091318 | videoA.mkv (1 091 kb/s)
1505121 | videoB.mkv (1 505 kb/s)
8803070 | videoD.mkv (8 803 kb/s)
11192962 | videoC.mkv (11.2 Mb/s)

How it works

Running mediainfo with a template through the Inform parameter we ask print firstly OverallBitRate with only numeric characters.

We ask to look for all file of the folder recursively matching *.

Then we pipe all the result into the sort command, with the -n parameters indicating we are sorting numeric values.

As the later character of %OverallBitRate% is non-numeric (space is not a numeric character), sort -n will only consider firsts numeric characters. That's means that sort -n with look to digits before the | separation which separate the overall bit rate and the file name.

Notes

Per line, mediainfo seem to be limited to only one section using the --Inform parameters. So if FileName would be printed, you can only get the OverallBitRate instead of BitRate (which is really close) as BitRate is in Video section and OverallBitRate however is in the General section as the file name is.

The difference is that OverallBitRate also contain audio bit rate along the video.

As seen, that's not really a python script: mediainfo itself could do most of the work making the python script non required.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .