Fixed check_video.py on Windows

using a cross-platform workaround


fixed proactor use in the SDK


fixed linter
This commit is contained in:
Brannon King 2020-01-30 10:37:08 -07:00 committed by Lex Berezhny
parent 47e8f74da9
commit a90b60799a
4 changed files with 44 additions and 20 deletions

View file

@ -1,5 +1,6 @@
import os import os
import re import re
import platform
import sys import sys
import typing import typing
import logging import logging
@ -461,6 +462,13 @@ class BaseConfig:
if self.persisted.upgrade(): if self.persisted.upgrade():
self.persisted.save() self.persisted.save()
@property
def needs_proactor(self):
major, minor, _ = platform.python_version_tuple()
if int(major) > 3 or (int(major) == 3 and int(minor) > 7):
return False
return platform.system() == "Windows"
class TranscodeConfig(BaseConfig): class TranscodeConfig(BaseConfig):

View file

@ -262,6 +262,8 @@ def setup_logging(logger: logging.Logger, args: argparse.Namespace, conf: Config
def run_daemon(args: argparse.Namespace, conf: Config): def run_daemon(args: argparse.Namespace, conf: Config):
if conf.needs_proactor:
asyncio.set_event_loop(asyncio.ProactorEventLoop())
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
if args.verbose is not None: if args.verbose is not None:
loop.set_debug(True) loop.set_debug(True)

View file

@ -21,7 +21,8 @@ class VideoFileAnalyzer:
return False return False
async def _execute(self, command, arguments): async def _execute(self, command, arguments):
process = await asyncio.create_subprocess_exec(self._conf.ffmpeg_folder + command, *shlex.split(arguments), args = shlex.split(arguments)
process = await asyncio.create_subprocess_exec(self._conf.ffmpeg_folder + command, *args,
stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
stdout, stderr = await process.communicate() # returns when the streams are closed stdout, stderr = await process.communicate() # returns when the streams are closed
return stdout.decode() + stderr.decode(), process.returncode return stdout.decode() + stderr.decode(), process.returncode
@ -34,7 +35,7 @@ class VideoFileAnalyzer:
code = -1 code = -1
version = "" version = ""
if code != 0 or not version.startswith(name): if code != 0 or not version.startswith(name):
raise Exception(f"Unable to locate or run {name}. Please install FFmpeg " raise FileNotFoundError(f"Unable to locate or run {name}. Please install FFmpeg "
f"and ensure that it is callable via PATH or conf.ffmpeg_folder") f"and ensure that it is callable via PATH or conf.ffmpeg_folder")
return version return version
@ -54,7 +55,7 @@ class VideoFileAnalyzer:
def _verify_container(self, scan_data: json): def _verify_container(self, scan_data: json):
container = scan_data["format"]["format_name"] container = scan_data["format"]["format_name"]
log.debug(" Detected container %s", container) log.debug(" Detected container is %s", container)
if not self._matches(container.split(","), ["webm", "mp4", "3gp", "ogg"]): if not self._matches(container.split(","), ["webm", "mp4", "3gp", "ogg"]):
return "Container format is not in the approved list of WebM, MP4. " \ return "Container format is not in the approved list of WebM, MP4. " \
f"Actual: {container} [{scan_data['format']['format_long_name']}]" f"Actual: {container} [{scan_data['format']['format_long_name']}]"
@ -65,7 +66,7 @@ class VideoFileAnalyzer:
if stream["codec_type"] != "video": if stream["codec_type"] != "video":
continue continue
codec = stream["codec_name"] codec = stream["codec_name"]
log.debug(" Detected video codec %s encoding %s", codec, stream["pix_fmt"]) log.debug(" Detected video codec is %s, format is %s", codec, stream["pix_fmt"])
if not self._matches(codec.split(","), ["h264", "vp8", "vp9", "av1", "theora"]): if not self._matches(codec.split(","), ["h264", "vp8", "vp9", "av1", "theora"]):
return "Video codec is not in the approved list of H264, VP8, VP9, AV1, Theora. " \ return "Video codec is not in the approved list of H264, VP8, VP9, AV1, Theora. " \
f"Actual: {codec} [{stream['codec_long_name']}]" f"Actual: {codec} [{stream['codec_long_name']}]"
@ -82,7 +83,7 @@ class VideoFileAnalyzer:
return "" return ""
bit_rate = float(scan_data["format"]["bit_rate"]) bit_rate = float(scan_data["format"]["bit_rate"])
log.debug(" Detected bitrate %s Mbps", str(bit_rate / 1000000.0)) log.debug(" Detected bitrate is %s Mbps", str(bit_rate / 1000000.0))
pixels = -1.0 pixels = -1.0
for stream in scan_data["streams"]: for stream in scan_data["streams"]:
if stream["codec_type"] == "video": if stream["codec_type"] == "video":
@ -114,7 +115,7 @@ class VideoFileAnalyzer:
if stream["codec_type"] != "audio": if stream["codec_type"] != "audio":
continue continue
codec = stream["codec_name"] codec = stream["codec_name"]
log.debug(" Detected audio codec %s", codec) log.debug(" Detected audio codec is %s", codec)
if not self._matches(codec.split(","), ["aac", "mp3", "flac", "vorbis", "opus"]): if not self._matches(codec.split(","), ["aac", "mp3", "flac", "vorbis", "opus"]):
return "Audio codec is not in the approved list of AAC, FLAC, MP3, Vorbis, and Opus. " \ return "Audio codec is not in the approved list of AAC, FLAC, MP3, Vorbis, and Opus. " \
f"Actual: {codec} [{stream['codec_long_name']}]" f"Actual: {codec} [{stream['codec_long_name']}]"
@ -143,7 +144,7 @@ class VideoFileAnalyzer:
return "Audio is at least five dB lower than prime. " \ return "Audio is at least five dB lower than prime. " \
f"Actual max: {max_volume}, mean: {mean_volume}" f"Actual max: {max_volume}, mean: {mean_volume}"
log.debug(" Detected audio volume mean, max as %f dB, %f dB", mean_volume, max_volume) log.debug(" Detected audio volume has mean, max of %f, %f dB", mean_volume, max_volume)
return "" return ""

View file

@ -3,7 +3,9 @@
import asyncio import asyncio
import logging import logging
import sys import sys
import lbry.wallet # just to make the following line work:
# noinspection PyUnresolvedReferences
import lbry.wallet # needed to make the following line work (it's a bug):
from lbry.conf import TranscodeConfig from lbry.conf import TranscodeConfig
from lbry.file_analysis import VideoFileAnalyzer from lbry.file_analysis import VideoFileAnalyzer
@ -19,21 +21,15 @@ def enable_logging():
root.addHandler(handler) root.addHandler(handler)
async def main(): async def process_video(analyzer, video_file):
if len(sys.argv) < 2:
print("Usage: <path to video file>", file=sys.stderr)
sys.exit(1)
video_file = sys.argv[1]
enable_logging()
conf = TranscodeConfig()
analyzer = VideoFileAnalyzer(conf)
try: try:
await analyzer.verify_or_repair(True, False, video_file) await analyzer.verify_or_repair(True, False, video_file)
print("No concerns. Ship it!") print("No concerns. Ship it!")
except FileNotFoundError as e:
print(str(e))
except Exception as e: except Exception as e:
print(str(e)) print(str(e))
transcode = input("Would you like repair this via transcode now? [y/N] ") transcode = input("Would you like to make a repaired clone now? [y/N] ")
if transcode == "y": if transcode == "y":
try: try:
new_video_file = await analyzer.verify_or_repair(True, True, video_file) new_video_file = await analyzer.verify_or_repair(True, True, video_file)
@ -42,5 +38,22 @@ async def main():
print("Unable to complete the transcode. Message: ", str(e)) print("Unable to complete the transcode. Message: ", str(e))
def main():
if len(sys.argv) < 2:
print("Usage: check_video.py <path to video file>", file=sys.stderr)
sys.exit(1)
enable_logging()
video_file = sys.argv[1]
conf = TranscodeConfig()
analyzer = VideoFileAnalyzer(conf)
loop = asyncio.ProactorEventLoop() if conf.needs_proactor else asyncio.get_event_loop()
try:
loop.run_until_complete(process_video(analyzer, video_file))
except KeyboardInterrupt:
pass
if __name__ == '__main__': if __name__ == '__main__':
asyncio.run(main()) main()