Mercurial > code > home > repos > light9
view light9/vidref/moviestore.py @ 1941:0dc3715050cf
video recorder now makes mp4 per song
Ignore-this: 9d60ecca4c1ab1ab99340addd2d2d264
author | drewp@bigasterisk.com |
---|---|
date | Tue, 04 Jun 2019 16:24:12 +0000 |
parents | |
children |
line wrap: on
line source
import os from bisect import bisect_left from rdflib import URIRef import sys sys.path.append( '/home/drewp/Downloads/moviepy/lib/python2.7/site-packages') # for moviepy from moviepy.video.io.ffmpeg_writer import FFMPEG_VideoWriter from moviepy.video.io.ffmpeg_reader import FFMPEG_VideoReader class _ResourceDir(object): """the disk files for a resource""" def __init__(self, root, uri): self.root, self.uri = root, uri u = self.uri.replace('http://', '').replace('/', '_') self.topDir = os.path.join(self.root, u) try: os.makedirs(self.topDir) except OSError: pass def videoPath(self): return os.path.join(self.topDir, 'video.avi') def indexPath(self): return os.path.join(self.topDir, 'frame_times') class Writer(object): """saves a video of a resource, receiving a frame at a time. Frame timing does not have to be regular.""" def __init__(self, root, uri): self.rd = _ResourceDir(root, uri) self.ffmpegWriter = None # lazy since we don't know the size yet self.index = open(self.rd.indexPath(), 'w') self.framesWritten = 0 def save(self, t, img): if self.ffmpegWriter is None: self.ffmpegWriter = FFMPEG_VideoWriter( filename=self.rd.videoPath(), size=img.size, fps=10, # doesn't matter, just for debugging playbacks codec='libx264') self.ffmpegWriter.write_frame(img) self.framesWritten = self.framesWritten + 1 self.index.write('%d %g\n' % (self.framesWritten, t)) def close(self): if self.ffmpegWriter is not None: self.ffmpegWriter.close() self.index.close() class Reader(object): def __init__(self, resourceDir): self.timeFrame = [] for line in open(resourceDir.indexPath()): f, t = line.strip().split() self.timeFrame.append((float(t), int(f))) self._reader = FFMPEG_VideoReader(resourceDir.videoPath()) def getFrame(self, t): i = bisect_left(self.timeFrame, (t, None)) i = min(i, len(self.timeFrame) - 1) f = self.timeFrame[i][1] return self._reader.get_frame(f) class MultiReader(object): """loads the nearest existing frame of a resource's video. Supports random access of multiple resources.""" def __init__(self, root): self.root = root # these should cleanup when they haven't been used in a while self.readers = {} # uri: Reader def getFrame(self, uri, t): if uri not in self.readers: #self.readers.close all and pop them self.readers[uri] = Reader(_ResourceDir(self.root, uri)) return self.readers[uri].getFrame(t) if __name__ == '__main__': from PIL import Image take = URIRef( 'http://light9.bigasterisk.com/show/dance2015/song10/1434249076/') if 0: w = Writer('/tmp/ms', take) for fn in sorted( os.listdir( '/home/drewp/light9-vidref/play-light9.bigasterisk.com_show_dance2015_song10/1434249076' )): t = float(fn.replace('.jpg', '')) jpg = Image.open( '/home/drewp/light9-vidref/play-light9.bigasterisk.com_show_dance2015_song10/1434249076/%08.03f.jpg' % t) jpg = jpg.resize((450, 176)) w.save(t, jpg) w.close() else: r = MultiReader('/tmp/ms') print((r.getFrame(take, 5.6)))