mirror of
https://github.com/mediacms-io/mediacms.git
synced 2024-12-01 04:34:30 +01:00
78 lines
2.0 KiB
Python
78 lines
2.0 KiB
Python
# ffmpeg only backend
|
|
|
|
from subprocess import PIPE, Popen
|
|
import locale
|
|
import re
|
|
import logging
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class VideoEncodingError(Exception):
|
|
def __init__(self, *args, **kwargs):
|
|
self.message = args[0]
|
|
super(VideoEncodingError, self).__init__(*args, **kwargs)
|
|
|
|
|
|
RE_TIMECODE = re.compile(r"time=(\d+:\d+:\d+.\d+)")
|
|
console_encoding = locale.getdefaultlocale()[1] or "UTF-8"
|
|
|
|
|
|
class FFmpegBackend(object):
|
|
name = "FFmpeg"
|
|
|
|
def __init__(self):
|
|
pass
|
|
|
|
def _spawn(self, cmd):
|
|
try:
|
|
return Popen(
|
|
cmd,
|
|
shell=False,
|
|
stdin=PIPE,
|
|
stdout=PIPE,
|
|
stderr=PIPE,
|
|
close_fds=True,
|
|
)
|
|
except OSError as e:
|
|
raise VideoEncodingError("Error while running ffmpeg", e)
|
|
|
|
def _check_returncode(self, process):
|
|
ret = {}
|
|
stdout, stderr = process.communicate()
|
|
ret["code"] = process.returncode
|
|
return ret
|
|
|
|
def encode(self, cmd):
|
|
process = self._spawn(cmd)
|
|
buf = output = ""
|
|
while True:
|
|
out = process.stderr.read(10)
|
|
|
|
if not out:
|
|
break
|
|
try:
|
|
out = out.decode(console_encoding)
|
|
except UnicodeDecodeError:
|
|
out = ""
|
|
output = output[-500:] + out
|
|
buf = buf[-500:] + out
|
|
try:
|
|
line, buf = buf.split("\r", 1)
|
|
except BaseException:
|
|
continue
|
|
|
|
progress = RE_TIMECODE.findall(line)
|
|
if progress:
|
|
progress = progress[0]
|
|
yield progress
|
|
|
|
process_check = self._check_returncode(process)
|
|
if process_check["code"] != 0:
|
|
raise VideoEncodingError(output[-1000:]) # output could be huge
|
|
|
|
if not output:
|
|
raise VideoEncodingError("No output from FFmpeg.")
|
|
|
|
yield output[-1000:] # output could be huge
|