1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
|
#! /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()
|