Python Script to Check Movie Runtimes

  Thread Rating:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Post Reply
count_zero Offline
Junior Member
Posts: 16
Joined: Jan 2011
Reputation: 0
Location: Little Rock, AR
Post: #1
I just installed xbmc a few months ago and use it to view all of my movies.
I've had a couple of handbrake movie rips fail silently--that is, the movie runs fine the first 45 minutes, and then stops because the file is incomplete. I had this happen to me twice in the last month, which is very frustrating (and embarrassing) if you want to see the end of a movie.Wink

So, I wanted to check my video library (+1000 files) without having to play each file to the end. I wrote a small python script to automate this process for me.

This very short script requires mplayer (to calculate runtimes) and IMDbPY (a python module API for IMDb, http://imdbpy.sourceforge.net/). I wrote it on Linux, but it *might* work on other OSes if you change the location of the mplayer executable in the script.

Code:
#!/usr/bin/env python
# cklength.py
# count_zero 2011
# This free software is licensed under the GPL (http://www.gnu.org/licenses/gpl.html)
# Check encoded movie length, compare it to feature length using IMDb
# Requires mplayer and IMDbPY to run

import sys
import os
import re
import subprocess
import os.path
import imdb

# Change this to your mplayer executable.
mplayer_exe = '/usr/bin/mplayer'

def get_feature_length(myfile):
    """ Check IMDb for the movie, search based on the filename.
    Will return the runtime of the first movie found, in minutes."""
    name = os.path.basename(myfile).split('.')[0]
    i = imdb.IMDb()
    try:
    m = i.search_movie(name)[0]
    i.update(m)
    runtime = m['runtimes'][0]
    title = m['title']
    return name, title, runtime
    except:
    return name, 'not found', 'unknown'

def get_encoded_length(myfile):
    """ Use mplayer to calculate the length of the movie file.
    Will return the runtime, in minutes."""
    abs_myfile = os.path.abspath(myfile)
    try:
    command = '%s -identify -frames 0 -vc null -vo null -ao null "%s"' % (mplayer_exe, abs_myfile)
    length_re = re.compile('ID_LENGTH=.*')
    p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    length = p.communicate()[0]
    mylength = int(length_re.findall(length)[0].lstrip('ID_LENGTH=').split('.')[0]) / 60
    return mylength
    except:
    return 'unknown'
    
if __name__ == "__main__":
    myfiles = sys.argv[1:]
    for myfile in myfiles:
    length = get_encoded_length(myfile)
    name, title, runtime = get_feature_length(myfile)
    print '%s (IMDb name: %s) - %s min (local) / %s min (IMDb)' % (myfile, title, length, runtime)

I was able to search my entire collection (m4v and mkv files) with this command (on Linux):
Code:
find . \( -iname \*m4v -o -iname \*mkv \) -exec cklength.py '{}' \; > movie_runtimes.txt

The output for each movie looks like this:
Code:
Action/Bourne Ultimatum.m4v (IMDb name: The Bourne Ultimatum) - 115 min (local) / 115 min (IMDb)

The IMDb matches were not always perfect (the script searches IMDb based on the filename), but most were good enough.

This could probably be integrated into an xbmc script for a better presentation (things like flagging a file if the times differed significantly, etc.), but I haven't had the time to study the xbmc API for doing this.
(anyone with more knowledge than I have is welcome to it)

Maybe this is not a problem for many people, but this script helped me immensely and I wanted to share it. Let me know if it's useful.
Enjoy!Big Grin
find quote