Commit f1c46a7c authored by Michael Murtaugh's avatar Michael Murtaugh

catframes and srt code

parent b6aecb75
#!/usr/bin/env python
from __future__ import print_function
from argparse import ArgumentParser
from PIL import Image
import cv2, os, numpy, sys
p = ArgumentParser("cat frames together, optional SRT formatted output")
p.add_argument("input", nargs="+", default=[])
p.add_argument("--output", default=None, help="path to save movie, default: None (show live)")
p.add_argument("--fourcc", default="XVID", help="MJPG,mp4v,XVID")
p.add_argument("--framerate", type=float, default=25, help="output frame rate")
p.add_argument("--resize", default=False, action="store_true")
p.add_argument("--pad", default=False, action="store_true")
p.add_argument("--width", type=int, default=640, help="pre-detect resize width")
p.add_argument("--height", type=int, default=480, help="pre-detect resize height")
p.add_argument("--background", default="255,255,255")
p.add_argument("--srt", default=False, action="store_true")
args = p.parse_args()
def resize (img, w, h, interpolation = cv2.INTER_CUBIC):
ih, iw, ic = img.shape
if (ih > h) or (iw > w):
# try fitting width
sw = w
sh = int(sw * (float(ih)/iw))
if sh > h:
# fit height instead
sh = h
sw = int(sh * (float(iw)/ih))
return cv2.resize(img, (sw, sh), interpolation=interpolation)
return img
def pad (img, w, h, color=(0, 0, 0)):
ih, iw, ic = img.shape
top = (h - ih) / 2
bottom = h - ih - top
left = (w - iw) / 2
right = (w - iw - left)
return cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
def process_frame (frame):
global out, framecount
if args.resize:
frame = resize(frame, args.width, args.height)
if not args.pad:
frame = pad(frame, args.width, args.height, background)
framecount += 1
if args.output:
# VIDEO OUTPUT
if out == None:
out = cv2.VideoWriter()
out.open(args.output, fourcc, args.framerate, (args.width, args.height))
out.write(frame)
else:
# WINDOW DISPLAY
cv2.imshow('display', frame)
if cv2.waitKey(delay) & 0xFF == ord('q'):
raise Exception("stop")
def processGIF(path):
frame = Image.open(path)
nframes = 0
while frame:
# process frame
try:
nf = numpy.array(frame.convert("RGB"))
# RGB => BGR
nf = nf[:, :, ::-1]
process_frame(nf)
nframes += 1
except IOError:
break
try:
frame.seek( nframes )
except EOFError:
break
return nframes
def processVideo (path):
cap = cv2.VideoCapture(path)
count = 0
while cap.isOpened():
ret, frame = cap.read()
if frame == None:
cap.release()
return count
count += 1
process_frame(frame)
if args.srt:
from srt import timecode
delay = int(1.0 / args.framerate * 1000)
background = tuple([int(x) for x in args.background.split(",")])
fourcc = None
if args.output:
try:
fourcc = cv2.cv.CV_FOURCC(*args.fourcc)
except AttributeError:
fourcc = cv2.VideoWriter_fourcc(*args.fourcc)
framecount = 0
out = None
files = args.input
files.sort()
for f in files:
print (f, file=sys.stderr)
if args.srt:
print ("{0} -->\n{1}\n".format(timecode(float(framecount)/args.framerate), f))
b, ext = os.path.splitext(f)
ext = ext.lstrip(".").lower()
if ext == "gif":
processGIF (f)
else:
processVideo(f)
if out:
out.release()
else:
cv2.destroyAllWindows()
print ("Processed {0} frames".format(framecount), file=sys.stderr)
#!/usr/bin/env python
import srt
import sys
tt = srt.aasrtparse(sys.stdin, normalize=True)
print (tt)
print srt.unparse(tt)
import re
def srtparse (src):
""" parse srt src (string), returns list of dicts with start, end, timecode, content """
spat = re.compile(r"^(?:\d+\n)?((?:\d\d:)?\d\d:\d\d(?:,\d\d\d)? *--> *(?:(?:\d\d:)?\d\d:\d\d(?:,\d\d\d)?)?)$", re.M)
tcpat = re.compile(r"(?:(\d\d):)?(\d\d):(\d\d)(?:,(\d\d\d))? *--> *(?:(?:(\d\d):)?(\d\d):(\d\d)(?:,(\d\d\d))?)?")
# spat = re.compile(r"^(?:\d+\n)?(\d\d:\d\d:\d\d(?:[,\.]\d\d\d)? --> \d\d:\d\d:\d\d(?:[,\.]\d\d\d)?)$", re.M)
# tcpat = re.compile(r"(\d\d):(\d\d):(\d\d)(?:[,\.](\d\d\d))? --> (\d\d):(\d\d):(\d\d)(?:[,\.](\d\d\d))?")
tt = spat.split(src)
ret = []
for i in range(1, len(tt), 2):
timecode = tt[i]
content = tt[i+1]
tcs = tcpat.match(timecode).groups()
if tcs[3] == None:
start = (int(tcs[0])*3600) + (int(tcs[1])*60) + float(tcs[2])
else:
start = (int(tcs[0])*3600) + (int(tcs[1])*60) + float(tcs[2]+"."+tcs[3])
if tcs[4]:
if tcs[7] == None:
end = (int(tcs[4])*3600) + (int(tcs[5])*60) + float(tcs[6])
else:
end = (int(tcs[4])*3600) + (int(tcs[5])*60) + float(tcs[6]+"."+tcs[7])
else:
end = None
ret.append({
'start': start,
'end': end,
'timecode': timecode,
'content': content.strip()
})
return ret
AASRT_URL_PAT = re.compile(r"^(https?:\/\/.+?)$")
AASRT_TC_PAT = re.compile(r"^(?:(\d\d):)?(\d\d):(\d\d)(?:[,\.](\d{1,3}))? *--> *(?:(?:(\d\d):)?(\d\d):(\d\d)(?:[,\.](\d{1,3}))?)?$")
def parse_tc (tc, ret):
if tc != None:
ret['start'] = (int(tc[0] or 0) * 3600) + (int(tc[1]) * 60) + int(tc[2])
if tc[3] != None:
ret['start'] = ret['start'] + float("0."+tc[3])
if tc[5] != None:
ret['end'] = (int(tc[4] or 0) * 3600) + (int(tc[5]) * 60) + int(tc[6])
if tc[7] != None:
ret['end'] = ret['end'] + float("0."+tc[7])
return ret
def aasrt_iter(f, line=0):
url = None
tc = None
content = None
content_linestart = None
prev = None
curline = line
for line in f:
curline += 1
m = AASRT_URL_PAT.match(line)
if m:
if content != None:
yield parse_tc(tc, {'href': url, 'content': content, 'lineStart': content_linestart, 'lineEnd': curline-1})
url = m.group(1)
tc = None
content_linestart=curline
content = u''
prev = 'URL'
else:
m = AASRT_TC_PAT.match(line)
if m:
if prev != 'URL':
# freestanding timecode
if content != None:
yield parse_tc(tc, {'href': url, 'content': content, 'lineStart': content_linestart, 'lineEnd': curline-1})
content_linestart=curline
content = u''
tc = m.groups()
prev = 'TC'
else:
# Append content
if content == None:
content_linestart=curline
content = line
else:
content += line
prev = 'TEXT'
if content != None:
yield parse_tc(tc, {'href': url, 'content': content, 'lineStart': content_linestart, 'lineEnd': curline})
def aasrt_normalized_iter (f):
prev = None
cur = None
for cur in aasrt_iter(f):
if prev != None:
# prev.href => cur.href
if ('href' in prev) and (prev['href'] != None) and (('href' not in cur) or (cur['href'] == None)):
cur['href'] = prev['href']
# prev.end <= cur.start
if ('end' not in prev) and \
('start' in cur) and \
cur['href'] == prev['href']:
prev['end'] = cur['start']
yield prev
prev = cur
if cur != None:
yield cur
def aasrtparse (src, normalize=True):
if (type(src) == str or type(src) == unicode):
src = [x+"\n" for x in src.splitlines()]
if normalize:
return list(aasrt_normalized_iter(src))
else:
return list(aasrt_iter(src))
# spat = re.compile(r"^(?:(\d+|http:\/\/.+?)\n)?((?:\d\d:)?\d\d:\d\d(?:[,\.]\d{1,3})? *--> *(?:(?:\d\d:)?\d\d:\d\d(?:[,\.]\d{1,3})?)?)$", re.M)
def unparse(titles):
ret = ''
for i, title in enumerate(titles):
if 'end' in title:
ret += "{0}\n{1} --> {2}\n{3}".format(i, timecode(title['start']), timecode(title['end']), title['content'])
else:
ret += "{0}\n{1} --> {2}\n{3}".format(i, timecode(title['start']), timecode(title['start']+5), title['content'])
return ret
def timecode(secs, style='srt'):
opts = timecode.styles[style]
h = int(secs/3600)
secs -= h*3600
m = int(secs/60)
secs -= m*60
s = int(secs)
if h == 0 and opts['skipzerohours']:
r = "{0:02d}:{1:02d}".format(m, s)
else:
r = "{0:02d}:{1:02d}:{2:02d}".format(h, m, s)
if (secs - s > 0) or opts['alwaysfract']:
r += opts['delim']+("{:0.3f}".format(secs-s)[2:])
return r
timecode.styles = {
'srt': {
'delim': ',',
'alwaysfract': True,
'skipzerohours': False
},
'compactsrt': {
'delim': ',',
'alwaysfract': False,
'skipzerohours': True
},
'html5': {
'delim': '.',
'alwaysfract': False,
'skipzerohours': True
}
}
if __name__ == "__main__":
doc1 = """
01:02:03 -->
01:02:04.5 -->
http://ia700304.us.archive.org/4/items/etiquette_0709_librivox/etiquette_07_post.ogg
http://ia700304.us.archive.org/4/items/etiquette_0709_librivox/etiquette_07_post.ogg
http://ftp.belnet.be/FOSDEM/2008/maintracks/FOSDEM2008-largescale.ogg
02:04 -->
[[Large scale]]
02:15 -->
02:17 -->
http://cloud.vti.be/openhouse/video/02-OH-BartVandeput_20120221_a3v6-640x360.ogv
""".strip()
for t in aasrtparse(doc1):
print t
continue
print "---"
if t['href']:
print t['href']
if 'start' in t:
# print tc
if 'end' in t:
print timecode(t['start']), '-->', timecode(t['end'])
else:
print timecode(t['start']), '-->'
print t['content']
# from pprint import pprint
# for t in tt:
# print t
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment