#! /usr/bin/env python
# Play synchronous video and audio.
# Highly experimental!
import sys
import getopt
import string
import os
import VFile
import aifc
import gl, GL, DEVICE
import al, AL
def usage():
sys.stderr.write( \
'usage: aplay [-o offset] [-q qsize] videofile audiofile\n')
sys.exit(2)
def main():
offset = 0
qsize = 0 # This defaults to 1/10 second of sound
videofile = 'film.video'
audiofile = 'film.aiff'
try:
opts, args = getopt.getopt(sys.argv[1:], 'o:q:')
except getopt.error, msg:
sys.stderr.write(msg + '\n')
usage()
try:
for o, a in opts:
if o == '-o':
offset = string.atoi(a)
if o == '-q':
qsize = string.atoi(a)
except string.atoi_error:
sys.stderr.write(o + ' arg must be integer\n')
usage()
if len(args) > 2:
usage()
if args: videofile = args[0]
if args[1:]: audiofile = args[1]
if not os.path.exists(videofile) and \
os.path.exists(videofile + '.video'):
if not args[1:] and os.path.exists(videofile + '.aiff'):
audiofile = videofile + '.aiff'
videofile = videofile + '.video'
print 'Opening video input file..'
vin = VFile.VinFile(videofile)
print 'Opening audio input file..'
ain = aifc.open(audiofile, 'r')
print 'rate :', ain.getframerate()
print 'channels:', ain.getnchannels()
print 'frames :', ain.getnframes()
print 'width :', ain.getsampwidth()
print 'kbytes :', \
ain.getnframes() * ain.getnchannels() * ain.getsampwidth()
print 'Opening audio output port..'
c = al.newconfig()
c.setchannels(ain.getnchannels())
c.setwidth(ain.getsampwidth())
nullsample = '\0' * ain.getsampwidth()
samples_per_second = ain.getnchannels() * ain.getframerate()
if qsize <= 0: qsize = samples_per_second / 10
qsize = max(qsize, 512)
c.setqueuesize(qsize)
saveparams = [AL.OUTPUT_RATE, 0]
al.getparams(AL.DEFAULT_DEVICE, saveparams)
newparams = [AL.OUTPUT_RATE, ain.getframerate()]
al.setparams(AL.DEFAULT_DEVICE, newparams)
aport = al.openport(audiofile, 'w', c)
print 'Opening video output window..'
gl.foreground()
gl.prefsize(vin.width, vin.height)
wid = gl.winopen(videofile + ' + ' + audiofile)
gl.clear()
vin.initcolormap()
print 'Playing..'
gl.qdevice(DEVICE.ESCKEY)
gl.qdevice(DEVICE.LEFTARROWKEY)
gl.qdevice(DEVICE.RIGHTARROWKEY)
## gl.qdevice(DEVICE.UPARROWKEY)
## gl.qdevice(DEVICE.DOWNARROWKEY)
gl.qdevice(DEVICE.SPACEKEY)
while 1:
samples_written = 0
samples_read = 0
lastt = 0
pause = 0
while 1:
if gl.qtest():
dev, val = gl.qread()
if val == 1:
if dev == DEVICE.ESCKEY:
sys.exit(0)
elif dev == DEVICE.LEFTARROWKEY:
offset = offset - 100
print 'offset =', offset
elif dev == DEVICE.RIGHTARROWKEY:
offset = offset + 100
print 'offset =', offset
elif dev == DEVICE.SPACEKEY:
pause = (not pause)
if pause:
continue
try:
t, data, cdata = vin.getnextframe()
except EOFError:
break
t = int(t)
dt = t - lastt
lastt = t
target = samples_per_second * t / 1000
n = target - samples_written + qsize - offset
if n > 0:
# This call will block until the time is right:
try:
samples = ain.readframes(n)
except EOFError:
samples = ''
k = len(samples) / len(nullsample)
samples_read = samples_read + k
if k < n:
samples = samples + (n-k) * nullsample
aport.writesamps(samples)
samples_written = samples_written + n
vin.showframe(data, cdata)
while 1:
try:
samples = ain.readframes(qsize)
except EOFError:
break
if not samples:
break
aport.writesamps(samples)
k = len(samples) / len(nullsample)
samples_read = samples_read + k
samples_written = samples_written + k
print samples_read, 'samples ==',
print samples_read * 1.0 / samples_per_second, 'sec.'
print lastt, 'milliseconds'
print 'Restarting..'
ain.close()
ain = aifc.open(audiofile, 'r')
vin.rewind()
main()
|