Skip to content

Commit

Permalink
fix(clipper): add warning and prompt to disable potentially unsupport…
Browse files Browse the repository at this point in the history
…ed video download protocols m3u8/m3u8_native

* ffmpeg seems to try to stream/download the entire video and sometimes fails to produce output
* m3u8/m3u8_native may be the best available quality in some cases and users may prefer to use the --download-video or --input-video option to work around this issue
  • Loading branch information
exwm committed Aug 12, 2023
1 parent ae3c172 commit 932368e
Showing 1 changed file with 46 additions and 11 deletions.
57 changes: 46 additions & 11 deletions src/clipper/ytc_settings.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import importlib
import json
import os
import re
import sys
from pathlib import Path
from typing import Any, Dict, List
from typing import Any, Dict, List, Tuple

from clipper import util, ytdl_importer
from clipper.clip_maker import getDefaultEncodeSettings
Expand Down Expand Up @@ -133,6 +134,47 @@ def getInputVideo(cs: ClipperState) -> None:

def getVideoInfo(cs: ClipperState) -> None:
settings = cs.settings

UNSUPPORTED_STREAMING_PROTOCOLS = ["m3u8", "m3u8_native"]

videoInfo, audioInfo = _getVideoInfo(cs)

if not settings["downloadVideo"] and "protocol" in videoInfo and videoInfo["protocol"] in UNSUPPORTED_STREAMING_PROTOCOLS:
logger.warning(f'In streaming mode, got video with unsupported protocol {videoInfo["protocol"]}.')
logger.warning(f'Unsupported streaming mode protocols: {UNSUPPORTED_STREAMING_PROTOCOLS}')
logger.warning(
f'm3u8 and m3u8_native protocols may require streaming/downloading the entire video before trimming and may fail')

logger.warning(
f'If an unsupported streaming mode protocol is preferred, please use a non-streaming mode with the --download-video or --input-video options')

response = input(r"Disable potentially unsupported protocols? (y/n): ")
if response in {"yes", "y"}:
logger.info(f'Retrying with potentially unsupported protocols disabled.')
disableYdlProtocols(settings, UNSUPPORTED_STREAMING_PROTOCOLS)
videoInfo, audioInfo = _getVideoInfo(cs)
else:
logger.warning(f'Continuing with potentially unsupported protocol {videoInfo["protocol"]}')

if settings["downloadVideo"]:
settings["inputVideo"] = settings["downloadVideoPath"]
else:
settings["videoURL"] = videoInfo["url"]

settings["audiobr"] = int(audioInfo["abr"])

settings["audioURL"] = audioInfo["url"]

getMoreVideoInfo(cs, videoInfo, audioInfo)


def disableYdlProtocols(settings: Settings, protocols: List[str]):
disableClause = "".join(f'[protocol!={protocol}]' for protocol in protocols)
settings["format"] = f'({settings["format"]}){disableClause}'


def _getVideoInfo(cs: ClipperState) -> Tuple[Dict[str, Any], Dict[str, Any]]:
settings = cs.settings
cp = cs.clipper_paths

ydl_opts = {
Expand All @@ -153,6 +195,7 @@ def getVideoInfo(cs: ClipperState) -> None:
if getattr(sys, "frozen", False):
ydl_opts["ffmpeg_location"] = cp.ffmpegPath

importlib.reload(ytdl_importer.youtube_dl)
with ytdl_importer.youtube_dl.YoutubeDL(ydl_opts) as ydl:
if settings["downloadVideo"]:
ydl_info: Dict[str, Any] = ydl.extract_info(settings["videoURL"], download=True) # type: ignore
Expand All @@ -163,21 +206,13 @@ def getVideoInfo(cs: ClipperState) -> None:
if "requested_formats" in ydl_info:
videoInfo = ydl_info["requested_formats"][0]
audioInfo = ydl_info["requested_formats"][1]
settings["mergedStreams"] = False
else:
videoInfo = ydl_info
audioInfo = videoInfo
settings["mergedStreams"] = True

if settings["downloadVideo"]:
settings["inputVideo"] = settings["downloadVideoPath"]
else:
settings["videoURL"] = videoInfo["url"]

settings["audiobr"] = int(audioInfo["abr"])

settings["audioURL"] = audioInfo["url"]

getMoreVideoInfo(cs, videoInfo, audioInfo)
return videoInfo, audioInfo


def getMoreVideoInfo(cs: ClipperState, videoInfo: Dict, audioInfo: Dict) -> None:
Expand Down

0 comments on commit 932368e

Please sign in to comment.