#!/usr/bin/env python """ getMovieInfo.py Extract some info from a QuickTime movie, especially the first (or title) image of a/the video track using PIL. Adapted from plat-mac/videoreader.py... """ import os, sys from Carbon import Qt from Carbon import QuickTime from Carbon import Qd from Carbon import Qdoffs from Carbon import QDOffscreen # from Carbon import Res from PIL import Image def extract(path): # setup Qt.EnterMovies() fd = Qt.OpenMovieFile(path, 0) # basics movie, d1, d2 = Qt.NewMovieFromFile(fd, 0, 0) movietimescale = movie.GetMovieTimeScale() videotrack = movie.GetMovieIndTrackType( 1, QuickTime.VisualMediaCharacteristic, QuickTime.movieTrackCharacteristic) videomedia = videotrack.GetTrackMedia() videotimescale = videomedia.GetMediaTimeScale() # x0, y0, x1, y1 = movie.GetMovieBox() videodescr = {'width':(x1-x0), 'height':(y1-y0)} print "frame size:", videodescr # dur = videotrack.GetTrackDuration() dur_ms, d1, d2 = Qt.ConvertTimeScale( (dur, movietimescale, None), 1000) print "duration in milliseconds:", dur_ms # flags = QuickTime.nextTimeStep flags = flags | QuickTime.nextTimeEdgeOK videocurtime = 0 moviecurtime, d1, d2 = Qt.ConvertTimeScale( (videocurtime, videotimescale, None), movietimescale) movie.SetMovieTimeValue(moviecurtime) movie.MoviesTask(0) # image extraction old_port, old_dev = Qdoffs.GetGWorld() try: movie_w = videodescr['width'] movie_h = videodescr['height'] movie_rect = (0, 0, movie_w, movie_h) gworld = Qdoffs.NewGWorld( 32, movie_rect, None, None, QDOffscreen.keepLocal) pixmap = gworld.GetGWorldPixMap() Qdoffs.LockPixels(pixmap) Qdoffs.SetGWorld(gworld.as_GrafPtr(), None) Qd.EraseRect(movie_rect) movie.SetMovieGWorld(gworld.as_GrafPtr(), None) movie.SetMovieBox(movie_rect) movie.SetMovieActive(1) movie.MoviesTask(0) movie.SetMoviePlayHints( QuickTime.hintsHighQuality, QuickTime.hintsHighQuality) except: Qdoffs.SetGWorld(old_port, old_dev) rowbytes = Qdoffs.GetPixRowBytes(pixmap) width = videodescr['width'] height = videodescr['height'] start = 0 rv = '' for i in range(height): nextline = Qdoffs.GetPixMapBytes(pixmap, start, width*4) start = start + rowbytes rv = rv + nextline # convert from ARGB to RGBA (faster/better anyone?) data = [] for i in xrange(0, width*height*4, 4): a, r, g, b = rv[i:i+4] data.append(r + g + b + a) data = ''.join(data) # save image using PIL img = Image.fromstring("RGBA", (width, height), data) out = os.path.splitext(path)[0] + ".jpeg" img.save(out, "JPEG") # needed to prevent a bus error videomedia = None videotrack = None movie = None path = "myMovie.mov" extract(path)