|
3 | 3 | Grab frames from a video file.
|
4 | 4 | """
|
5 | 5 |
|
| 6 | +import os |
| 7 | +import os.path |
| 8 | +import re |
| 9 | +import shutil |
6 | 10 | import sys
|
7 | 11 | import tempfile
|
8 |
| -from PIL import Image |
| 12 | +#from PIL import Image |
9 | 13 |
|
10 |
| -from common.misc import runcmd |
| 14 | +import common.misc |
| 15 | +from common.stats import stats |
11 | 16 |
|
| 17 | +#def grab_frame(filename, framenumber, FPS=29.97): |
| 18 | +# """ |
| 19 | +# Grab a certain from an video file, and return it as a PIL Image |
| 20 | +# TODO: Don't hardcode FPS. |
| 21 | +# TODO: Use a better library for this. |
| 22 | +# """ |
| 23 | +# tmp = tempfile.NamedTemporaryFile(suffix=".png") |
| 24 | +# framesec = 1. * framenumber / FPS |
| 25 | +# cmd = "ffmpeg -i %s -y -vcodec png -vframes 1 -an -ss %f -f rawvideo %s" % (filename, framesec, tmp.name) |
| 26 | +# print >> sys.stderr, cmd |
| 27 | +# runcmd(cmd) |
| 28 | +# im = Image.open(tmp.name) |
| 29 | +# tmp.close() |
| 30 | +# return im |
12 | 31 |
|
13 |
| -def grab_frame(filename, framenumber, FPS=29.97): |
| 32 | +def frames(filename, maxframes=None): |
14 | 33 | """
|
15 |
| - Grab a certain from an video file, and return it as a PIL Image |
16 |
| - TODO: Don't hardcode FPS. |
| 34 | + Iterate over the frames in a video file. |
| 35 | + Yields (frame number, PNG filename, total frames). |
| 36 | + maxframes: Maximum number of frames to return. |
17 | 37 | TODO: Use a better library for this.
|
18 | 38 | """
|
19 |
| - tmp = tempfile.NamedTemporaryFile(suffix=".png") |
20 |
| - framesec = 1. * framenumber / FPS |
21 |
| - cmd = "ffmpeg -i %s -y -vcodec png -vframes 1 -an -ss %f -f rawvideo %s" % (filename, framesec, tmp.name) |
22 |
| - print >> sys.stderr, cmd |
23 |
| - runcmd(cmd) |
24 |
| - im = Image.open(tmp.name) |
25 |
| - tmp.close() |
26 |
| - return im |
| 39 | + dir = tempfile.mkdtemp() |
| 40 | + inre = re.compile("in.*.jpg") |
| 41 | + try: |
| 42 | + # Decompose video into images |
| 43 | + # I learned this command from here: http://electron.mit.edu/~gsteele/ffmpeg/ |
| 44 | + if maxframes is None: |
| 45 | + cmd = "ffmpeg -sameq -y -r 30 -i %s %s" % (filename, os.path.join(dir, 'in%05d.jpg')) |
| 46 | + else: |
| 47 | + cmd = "ffmpeg -sameq -y -vframes %d -r 30 -i %s %s" % (maxframes, filename, os.path.join(dir, 'in%05d.jpg')) |
| 48 | + print >> sys.stderr, "Decomposing video to images:", cmd, "\n" |
| 49 | + common.misc.runcmd(cmd) |
| 50 | + print >> sys.stderr, stats() |
| 51 | + |
| 52 | + # Find all files to process |
| 53 | + infiles = [] |
| 54 | + for f in os.listdir(dir): |
| 55 | + if inre.match(f): |
| 56 | + infiles.append(f) |
| 57 | + infiles.sort() |
| 58 | + |
| 59 | + for i, f in enumerate(infiles): |
| 60 | + yield i, os.path.join(dir, f), len(infiles) |
| 61 | + |
| 62 | + |
| 63 | + finally: |
| 64 | + print >> sys.stderr, "Removing dir %s" % dir |
| 65 | + shutil.rmtree(dir) |
27 | 66 |
|
28 | 67 | if __name__ == "__main__":
|
29 | 68 | assert len(sys.argv) == 2
|
30 | 69 | grab_image(sys.argv[1], 0)
|
| 70 | + |
0 commit comments