mirror of
https://github.com/iperov/DeepFaceLive
synced 2025-07-06 04:52:14 -07:00
fix ffmpeg
This commit is contained in:
parent
7aaa15340c
commit
3be99ce9f3
5 changed files with 73 additions and 31 deletions
|
@ -1 +1 @@
|
||||||
from .ffmpeg import probe, run, run_play
|
from .ffmpeg import probe, run
|
|
@ -1,8 +1,8 @@
|
||||||
import json
|
import json
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
def run(args, pipe_stdin=False, pipe_stdout=False, pipe_stderr=False, quiet_stderr=False) -> Union[subprocess.Popen,None]:
|
||||||
def run(args, pipe_stdin=False, pipe_stdout=False, pipe_stderr=False, quiet_std_err=False):
|
|
||||||
"""
|
"""
|
||||||
run ffmpeg process
|
run ffmpeg process
|
||||||
|
|
||||||
|
@ -10,11 +10,12 @@ def run(args, pipe_stdin=False, pipe_stdout=False, pipe_stderr=False, quiet_std_
|
||||||
otherwise None
|
otherwise None
|
||||||
"""
|
"""
|
||||||
args = ['ffmpeg'] + args
|
args = ['ffmpeg'] + args
|
||||||
|
|
||||||
stdin_stream = subprocess.PIPE if pipe_stdin else None
|
stdin_stream = subprocess.PIPE if pipe_stdin else None
|
||||||
stdout_stream = subprocess.PIPE if pipe_stdout else None
|
stdout_stream = subprocess.PIPE if pipe_stdout else None
|
||||||
stderr_stream = subprocess.PIPE if pipe_stderr else None
|
stderr_stream = subprocess.PIPE if pipe_stderr else None
|
||||||
|
|
||||||
if quiet_std_err and not pipe_stderr:
|
if quiet_stderr and not pipe_stderr:
|
||||||
stderr_stream = subprocess.DEVNULL
|
stderr_stream = subprocess.DEVNULL
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -53,20 +54,3 @@ def probe(filename):
|
||||||
raise Exception('ffprobe', out, err)
|
raise Exception('ffprobe', out, err)
|
||||||
return json.loads(out.decode('utf-8'))
|
return json.loads(out.decode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def run_play():
|
|
||||||
args = ['ffplay',
|
|
||||||
'-f', 'rawvideo',
|
|
||||||
'-pix_fmt', 'bgr24',
|
|
||||||
'-s', '256x144',
|
|
||||||
'-'
|
|
||||||
]
|
|
||||||
stdin_stream = subprocess.PIPE
|
|
||||||
stdout_stream = None
|
|
||||||
stderr_stream = None#subprocess.DEVNULL
|
|
||||||
|
|
||||||
try:
|
|
||||||
return subprocess.Popen(args, stdin=stdin_stream, stdout=stdout_stream, stderr=stderr_stream)
|
|
||||||
except Exception as e:
|
|
||||||
print('ffplay exception: ', e)
|
|
||||||
return None
|
|
||||||
|
|
56
xlib/io/IOThreadLinesReader.py
Normal file
56
xlib/io/IOThreadLinesReader.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import threading
|
||||||
|
import time
|
||||||
|
from io import IOBase
|
||||||
|
from typing import List
|
||||||
|
from collections import deque
|
||||||
|
|
||||||
|
class IOThreadLinesReader:
|
||||||
|
"""
|
||||||
|
continuously reads lines from IO in background thread.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, io : IOBase, max_lines=None):
|
||||||
|
self._io = io
|
||||||
|
self._lock = threading.Lock()
|
||||||
|
self._lines = deque(maxlen=max_lines)
|
||||||
|
|
||||||
|
threading.Thread(target=self._proc, daemon=True).start()
|
||||||
|
|
||||||
|
def _proc(self):
|
||||||
|
io = self._io
|
||||||
|
lock = self._lock
|
||||||
|
lines = self._lines
|
||||||
|
|
||||||
|
while not io.closed and io.readable():
|
||||||
|
line = io.readline()
|
||||||
|
lock.acquire()
|
||||||
|
lines.append(line.decode('utf-8').rstrip())
|
||||||
|
lock.release()
|
||||||
|
if len(line) == 0:
|
||||||
|
break
|
||||||
|
time.sleep(0.01)
|
||||||
|
|
||||||
|
def get_lines(self, wait_new=True, till_eof=False) -> List[str]:
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
lock = self._lock
|
||||||
|
lines = self._lines
|
||||||
|
|
||||||
|
result = []
|
||||||
|
while True:
|
||||||
|
|
||||||
|
if len(lines) != 0:
|
||||||
|
lock.acquire()
|
||||||
|
result += lines
|
||||||
|
lines.clear()
|
||||||
|
lock.release()
|
||||||
|
|
||||||
|
if till_eof and len(result[-1]) != 0:
|
||||||
|
continue
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
if not till_eof and not wait_new:
|
||||||
|
return None
|
||||||
|
time.sleep(0.001)
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
from .IO import FormattedMemoryViewIO, FormattedFileIO
|
from .IO import FormattedMemoryViewIO, FormattedFileIO
|
||||||
|
from .IOThreadLinesReader import IOThreadLinesReader
|
|
@ -3,10 +3,10 @@ from typing import Tuple
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from xlib import ffmpeg as lib_ffmpeg
|
from xlib import ffmpeg as lib_ffmpeg
|
||||||
|
from xlib import io as lib_io
|
||||||
|
|
||||||
from .FramePlayer import FramePlayer
|
from .FramePlayer import FramePlayer
|
||||||
|
|
||||||
|
|
||||||
class VideoFilePlayer(FramePlayer):
|
class VideoFilePlayer(FramePlayer):
|
||||||
"""
|
"""
|
||||||
Play video track from the video file using subprocess ffmpeg.
|
Play video track from the video file using subprocess ffmpeg.
|
||||||
|
@ -125,22 +125,23 @@ class VideoFilePlayer(FramePlayer):
|
||||||
'-map', f'0:v:{self._stream_idx}',
|
'-map', f'0:v:{self._stream_idx}',
|
||||||
'pipe:']
|
'pipe:']
|
||||||
|
|
||||||
self._ffmpeg_proc = lib_ffmpeg.run (args, pipe_stdout=True, pipe_stderr=True)
|
self._ffmpeg_proc = ffmpeg_proc = lib_ffmpeg.run (args, pipe_stdout=True, pipe_stderr=True)
|
||||||
return self._ffmpeg_proc is not None
|
self._ffmpeg_proc_stderr_lines = None
|
||||||
|
if ffmpeg_proc is not None:
|
||||||
|
self._ffmpeg_proc_stderr_lines = lib_io.IOThreadLinesReader(ffmpeg_proc.stderr, max_lines=5)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _ffmpeg_next_frame(self, frames_idx_offset=1):
|
def _ffmpeg_next_frame(self, frames_idx_offset=1):
|
||||||
frame_buffer = None
|
frame_buffer = None
|
||||||
|
|
||||||
while frames_idx_offset != 0:
|
while frames_idx_offset != 0:
|
||||||
frame_buffer = self._ffmpeg_proc.stdout.read(self._ffmpeg_height*self._ffmpeg_width*3)
|
frame_buffer = self._ffmpeg_proc.stdout.read(self._ffmpeg_height*self._ffmpeg_width*3)
|
||||||
|
|
||||||
if len(frame_buffer) == 0:
|
if len(frame_buffer) == 0:
|
||||||
err = self._ffmpeg_proc.stderr.read()
|
# unpredicted end reached
|
||||||
err_lines = err.decode('utf-8').split('\r\n')
|
err = '\r\n'.join(self._ffmpeg_proc_stderr_lines.get_lines(till_eof=True)[-5:])
|
||||||
err = '\r\n'.join(err_lines[-5:])
|
|
||||||
|
|
||||||
# End reached
|
|
||||||
self._ffmpeg_stop()
|
self._ffmpeg_stop()
|
||||||
|
|
||||||
return None, err
|
return None, err
|
||||||
frames_idx_offset -= 1
|
frames_idx_offset -= 1
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue