I'm using the latest cvs version of pymedia. I used some printf's
in the source code and located (maybe) the problem. time_base
is never set so that in av_write_header in av_frac_init there is a divide
by 0/0.
-- Jonathan
#import numarray as N #import numarray.random_array as Ra #import numarray.fft as Fft #import numarray.nd_image as Nd #import numarray.memmap as Mm
import pymedia
import pymedia.muxer as muxer
import pymedia.video.vcodec as vcodec
import pymedia.video.ext_codecs as ext_codecs
#import wx
#import math, sys
#import os, tempfile, shutil
"""
def CountVideoFrames(filename):
file = open(filename, 'rb')
format = (filename.split('.')[-1]).lower()
dm = muxer.Demuxer(format)
s = file.read(390000)
r = dm.parse(s)
ss = filter(lambda x: x['type'] == muxer.CODEC_TYPE_VIDEO, dm.streams)
if len(ss) == 0:
raise RuntimeError, 'no video stream in file'
v_id = ss[0]['index']
vc = vcodec.Decoder(ss[0])
frame_count = 0
byte_count = 0
while len(s):
for d in r:
if d[0] == v_id:
vframe = vc.decode(d[1])
if vframe:
frame_count += 1
byte_count += vframe.size[0]*vframe.size[1]
#print "read frame", frame_count
s = file.read(100000)
r = dm.parse(s)
file.close()
return frame_count, byte_count
"""
class VideoReadOnlyFile:
def __init__(self, filename):
self.filename = filename
self.erst_frame = None
self._Open()
def _Open(self):
self.file = open(self.filename, 'rb')
format = (self.filename.split('.')[-1]).lower()
self.dm = muxer.Demuxer(format)
self.s = self.file.read(390000)
self.r = self.dm.parse(self.s)
self.ri = 0
ss = filter(lambda x: x['type'] == muxer.CODEC_TYPE_VIDEO, self.dm.streams)
if len(ss) == 0:
raise RuntimeError, 'no video stream in file'
self.v_id = ss[0]['index']
self.vc = vcodec.Decoder(ss[0])
def GetFrameSize(self):
if self.erst_frame == None:
params = self.vc.getParams()
return params['width'], params['height']
else:
return self.erst_frame.size
def GetFps(self):
params = self.vc.getParams()
return params['frame_rate']
def ReadFrame(self):
while len(self.s):
for i, d in enumerate(self.r[self.ri:]):
if d[0] == self.v_id:
vframe = self.vc.decode(d[1])
if vframe:
if i+1 >= len(self.r):
self.s = self.file.read(100000)
self.r = self.dm.parse(s)
self.ri = 0
else:
self.ri = i+1
self.erst_frame = vframe
return vframe
self.s = self.file.read(100000)
self.r = self.dm.parse(self.s)
return None
def ReadFrames(self, nframes):
frames = []
while len(frames) < nframes:
frame = self.ReadFrame()
if frame == None: break
frames.append(frame)
return frames
def Eof(self):
return not len(self.s)
def Reset(self):
self.Close()
self._Open()
def Close(self):
self.file.close()
class VideoWriteOnlyFile:
def __init__(self, filename, width, height, fps, format=None):
self.filename = filename
self.width, self.height = width, height
self.fps = fps
self.format = format
if format == None:
format = self.filename.split('.')[-1].lower()
try:
id = vcodec.getCodecID(format)
except pymedia.video.vcodec.VCodecError:
id = vcodec.getCodecID('mpeg1video')
self.mx = muxer.Muxer(format)
params = {
'id' : id,
'width' : self.width,
'height' : self.height,
'bitrate' : 2500000,
'gop_size' : 12,
'frame_rate' : self.fps,
'frame_rate_base' : 1,
'max_b_frames' : 2,
'deinterlace' : 0,
'type' : 0,
}
self.v_id = self.mx.addStream(muxer.CODEC_TYPE_VIDEO, params)
self.venc = vcodec.Encoder(params)
self.file = open(self.filename, 'wb')
print 'hello'
header = self.mx.start()
print 'yo'
self.file.write(header)
print 'bye'
def WriteFrame(self, vframe):
s1 = self.mx.write(self.v_id, self.venc.encode(vframe))
self.file.write(s1)
def WriteFrames(self, vframes):
for vframe in vframes:
self.WriteFrame(vframe)
def Close():
self.file.write(self.mx.end())
self.file.close()
if __name__ == '__main__':
vread = VideoReadOnlyFile('../downloads/Braindead.mpg')
vread.ReadFrame()
vread.Reset()
width, height = vread.GetFrameSize()
fps = vread.GetFps()
vwrite = VideoWriteOnlyFile('braindead.avi', width, height, fps)
print 'hello'
frame = 0
while not vread.Eof():
vframe = vread.ReadFrame()
vwrite.WriteFrame(vframe)
frame += 1
print 'Copied frame', frame
vread.Close()
vwrite.Close()
