use ffmpeg to merge mp4 files, support clip extraction from multiple parts

This commit is contained in:
j 2017-11-16 16:39:38 +01:00
parent 3204bc68f6
commit 959ffaba25
2 changed files with 27 additions and 10 deletions

View file

@ -498,14 +498,21 @@ class Item(models.Model):
p.wait()
return True
elif format == "mp4":
fd, tmp_output = tempfile.mkstemp('.mp4')
shutil.copy(streams[0], tmp_output)
for s in streams[1:]:
cmd = ['MP4Box', '-cat', s, tmp_output]
p = subprocess.Popen(cmd, stdout=open('/dev/null', 'w'), stderr=open('/dev/null', 'w'), close_fds=True)
fd, tmp_output_txt = tempfile.mkstemp('.txt')
with open(tmp_output_txt, 'w') as f:
f.write('\n'.join(["file '{}'".format(path) for path in streams]))
cmd = [
settings.FFMPEG,
'-nostats', '-loglevel', 'error',
'-y',
'-f', 'concat', '-safe', '0', '-i', tmp_output_txt,
'-c', 'copy',
output
]
p = subprocess.Popen(
cmd, stdout=open('/dev/null', 'w'), stderr=open('/dev/null', 'w'), close_fds=True)
p.wait()
shutil.copy(tmp_output, output)
os.unlink(tmp_output)
os.unlink(tmp_output_txt)
return True
else:
return None

View file

@ -1022,7 +1022,6 @@ def video(request, id, resolution, format, index=None, track=None):
path = stream.media.path
# server side cutting
# FIXME: this needs to join segments if needed
t = request.GET.get('t')
if t:
def parse_timestamp(s):
@ -1031,8 +1030,19 @@ def video(request, id, resolution, format, index=None, track=None):
return float(s)
t = list(map(parse_timestamp, t.split(',')))
ext = '.%s' % format
duration = stream.info['duration']
# multipart request beyond first part, merge parts and chop that
if not index and streams.count() > 1 and stream.info['duration'] < t[1]:
video = NamedTemporaryFile(suffix=ext)
r = item.merge_streams(video.name, resolution, format)
if not r:
return HttpResponseForbidden()
path = video.name
duration = sum(item.json['durations'])
content_type = mimetypes.guess_type(path)[0]
if len(t) == 2 and t[1] > t[0] and stream.info['duration'] >= t[1]:
if len(t) == 2 and t[1] > t[0] and duration >= t[1]:
response = HttpResponse(extract.chop(path, t[0], t[1]), content_type=content_type)
filename = u"Clip of %s - %s-%s - %s %s%s" % (
item.get('title'),