videoreader.py :  » Language-Interface » ChinesePython » chinesepython2.1.3-0.4 » Mac » Lib » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Language Interface » ChinesePython 
ChinesePython » chinesepython2.1.3 0.4 » Mac » Lib » videoreader.py
# Video file reader, using QuickTime
#
# This module was quickly ripped out of another software package, so there is a good
# chance that it does not work as-is and it needs some hacking.
#
# Jack Jansen, August 2000
#
import sys
import Qt
import QuickTime
import Qd
import Qdoffs
import QDOffscreen
import Res
import MediaDescr
import imgformat
import os
# import audio.format
import macfs

class VideoFormat:
  def __init__(self, name, descr, width, height, format):
    self.__name = name
    self.__descr = descr
    self.__width = width
    self.__height = height
    self.__format = format
    
  def getname(self):
    return self.__name
    
  def getdescr(self):
    return self.__descr
    
  def getsize(self):
    return self.__width, self.__height
    
  def getformat(self):
    return self.__format
    
class _Reader:
  def __init__(self, path):
    fsspec = macfs.FSSpec(path)
    fd = Qt.OpenMovieFile(fsspec, 0)
    self.movie, d1, d2 = Qt.NewMovieFromFile(fd, 0, 0)
    self.movietimescale = self.movie.GetMovieTimeScale()
    try:
      self.audiotrack = self.movie.GetMovieIndTrackType(1,
        QuickTime.AudioMediaCharacteristic, QuickTime.movieTrackCharacteristic)
      self.audiomedia = self.audiotrack.GetTrackMedia()
    except Qt.Error:
      self.audiotrack = self.audiomedia = None
      self.audiodescr = {}
    else:
      handle = Res.Handle('')
      n = self.audiomedia.GetMediaSampleDescriptionCount()
      self.audiomedia.GetMediaSampleDescription(1, handle)
      self.audiodescr = MediaDescr.SoundDescription.decode(handle.data)
      self.audiotimescale = self.audiomedia.GetMediaTimeScale()
      del handle
  
    try:  
      self.videotrack = self.movie.GetMovieIndTrackType(1,
        QuickTime.VisualMediaCharacteristic, QuickTime.movieTrackCharacteristic)
      self.videomedia = self.videotrack.GetTrackMedia()
    except Qt.Error:
      self.videotrack = self.videomedia = self.videotimescale = None
    if self.videotrack:
      self.videotimescale = self.videomedia.GetMediaTimeScale()
      x0, y0, x1, y1 = self.movie.GetMovieBox()
      self.videodescr = {'width':(x1-x0), 'height':(y1-y0)}
      self._initgworld()
    self.videocurtime = None
    self.audiocurtime = None

    
  def __del__(self):
    self.audiomedia = None
    self.audiotrack = None
    self.videomedia = None
    self.videotrack = None
    self.movie = None
    
  def _initgworld(self):
    old_port, old_dev = Qdoffs.GetGWorld()
    try:
      movie_w = self.videodescr['width']
      movie_h = self.videodescr['height']
      movie_rect = (0, 0, movie_w, movie_h)
      self.gworld = Qdoffs.NewGWorld(32,  movie_rect, None, None, QDOffscreen.keepLocal)
      self.pixmap = self.gworld.GetGWorldPixMap()
      Qdoffs.LockPixels(self.pixmap)
      Qdoffs.SetGWorld(self.gworld.as_GrafPtr(), None)
      Qd.EraseRect(movie_rect)
      self.movie.SetMovieGWorld(self.gworld.as_GrafPtr(), None)
      self.movie.SetMovieBox(movie_rect)
      self.movie.SetMovieActive(1)
      self.movie.MoviesTask(0)
      self.movie.SetMoviePlayHints(QuickTime.hintsHighQuality, QuickTime.hintsHighQuality)
      # XXXX framerate
    finally:
      Qdoffs.SetGWorld(old_port, old_dev)
    
  def _gettrackduration_ms(self, track):
    tracktime = track.GetTrackDuration()
    return self._movietime_to_ms(tracktime)
    
  def _movietime_to_ms(self, time):
    value, d1, d2 = Qt.ConvertTimeScale((time, self.movietimescale, None), 1000)
    return value
    
  def _videotime_to_ms(self, time):
    value, d1, d2 = Qt.ConvertTimeScale((time, self.videotimescale, None), 1000)
    return value
    
  def _audiotime_to_ms(self, time):
    value, d1, d2 = Qt.ConvertTimeScale((time, self.audiotimescale, None), 1000)
    return value
    
  def _videotime_to_movietime(self, time):
    value, d1, d2 = Qt.ConvertTimeScale((time, self.videotimescale, None),
        self.movietimescale)
    return value
    
  def HasAudio(self):
    return not self.audiotrack is None
    
  def HasVideo(self):
    return not self.videotrack is None
    
  def GetAudioDuration(self):
    if not self.audiotrack:
      return 0
    return self._gettrackduration_ms(self.audiotrack)

  def GetVideoDuration(self):
    if not self.videotrack:
      return 0
    return self._gettrackduration_ms(self.videotrack)
    
  def GetAudioFormat(self):
    bps = self.audiodescr['sampleSize']
    nch = self.audiodescr['numChannels']
    if nch == 1:
      channels = ['mono']
    elif nch == 2:
      channels = ['left', 'right']
    else:
      channels = map(lambda x: str(x+1), range(nch))
    if bps % 8:
      # Funny bits-per sample. We pretend not to understand
      blocksize = 0
      fpb = 0
    else:
      # QuickTime is easy (for as far as we support it): samples are always a whole
      # number of bytes, so frames are nchannels*samplesize, and there's one frame per block.
      blocksize = (bps/8)*nch
      fpb = 1
    if self.audiodescr['dataFormat'] == 'raw ':
      encoding = 'linear-excess'
    elif self.audiodescr['dataFormat'] == 'twos':
      encoding = 'linear-signed'
    else:
      encoding = 'quicktime-coding-%s'%self.audiodescr['dataFormat']
##    return audio.format.AudioFormatLinear('quicktime_audio', 'QuickTime Audio Format', 
##      channels, encoding, blocksize=blocksize, fpb=fpb, bps=bps)
    return channels, encoding, blocksize, fpb, bps
      
  def GetAudioFrameRate(self):
    return int(self.audiodescr['sampleRate'])
    
  def GetVideoFormat(self):
    width = self.videodescr['width']
    height = self.videodescr['height']
    return VideoFormat('dummy_format', 'Dummy Video Format', width, height, imgformat.macrgb)
    
  def GetVideoFrameRate(self):
    tv = self.videocurtime
    if tv == None:
      tv = 0
    flags = QuickTime.nextTimeStep|QuickTime.nextTimeEdgeOK
    tv, dur = self.videomedia.GetMediaNextInterestingTime(flags, tv, 1.0)
    dur = self._videotime_to_ms(dur)
    return int((1000.0/dur)+0.5)
    
  def ReadAudio(self, nframes, time=None):
    if not time is None:
      self.audiocurtime = time
    flags = QuickTime.nextTimeStep|QuickTime.nextTimeEdgeOK
    if self.audiocurtime == None:
      self.audiocurtime = 0
    tv = self.audiomedia.GetMediaNextInterestingTimeOnly(flags, self.audiocurtime, 1.0)
    if tv < 0 or (self.audiocurtime and tv < self.audiocurtime):
      return self._audiotime_to_ms(self.audiocurtime), None
    h = Res.Handle('')
    desc_h = Res.Handle('')
    size, actualtime, sampleduration, desc_index, actualcount, flags = \
      self.audiomedia.GetMediaSample(h, 0, tv, desc_h, nframes)
    self.audiocurtime = actualtime + actualcount*sampleduration
    return self._audiotime_to_ms(actualtime), h.data
    
  def ReadVideo(self, time=None):
    if not time is None:
      self.videocurtime = time
    flags = QuickTime.nextTimeStep
    if self.videocurtime == None:
      flags = flags | QuickTime.nextTimeEdgeOK
      self.videocurtime = 0
    tv = self.videomedia.GetMediaNextInterestingTimeOnly(flags, self.videocurtime, 1.0)
    if tv < 0 or (self.videocurtime and tv <= self.videocurtime):
      return self._videotime_to_ms(self.videocurtime), None
    self.videocurtime = tv
    moviecurtime = self._videotime_to_movietime(self.videocurtime)
    self.movie.SetMovieTimeValue(moviecurtime)
    self.movie.MoviesTask(0)
    return self._videotime_to_ms(self.videocurtime), self._getpixmapcontent()
    
  def _getpixmapcontent(self):
    """Shuffle the offscreen PixMap data, because it may have funny stride values"""
    rowbytes = Qdoffs.GetPixRowBytes(self.pixmap)
    width = self.videodescr['width']
    height = self.videodescr['height']
    start = 0
    rv = ''
    for i in range(height):
      nextline = Qdoffs.GetPixMapBytes(self.pixmap, start, width*4)
      start = start + rowbytes
      rv = rv + nextline
    return rv

def reader(url):
  try:
    rdr = _Reader(url)
  except IOError:
    return None
  return rdr

def _test():
  import img
  import MacOS
  Qt.EnterMovies()
  fss, ok = macfs.PromptGetFile('Video to convert')
  if not ok: sys.exit(0)
  path = fss.as_pathname()
  rdr = reader(path)
  if not rdr:
    sys.exit(1)
  dstfss, ok = macfs.StandardPutFile('Name for output folder')
  if not ok: sys.exit(0)
  dstdir = dstfss.as_pathname()
  num = 0
  os.mkdir(dstdir)
  videofmt = rdr.GetVideoFormat()
  imgfmt = videofmt.getformat()
  imgw, imgh = videofmt.getsize()
  timestamp, data = rdr.ReadVideo()
  while data:
    fname = 'frame%04.4d.jpg'%num
    num = num+1
    pname = os.path.join(dstdir, fname)
    print 'Writing', fname, imgw, imgh, len(data)
    wrt = img.writer(imgfmt, pname)
    wrt.width = imgw
    wrt.height = imgh
    wrt.write(data)
    timestamp, data = rdr.ReadVideo()
    MacOS.SetCreatorAndType(pname, 'ogle', 'JPEG')
    if num > 20: 
      print 'stopping at 20 frames so your disk does not fill up:-)'
      break
  print 'Total frames:', num
    
if __name__ == '__main__':
  _test()
  sys.exit(1)
    
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.