mirror of
https://github.com/ytdl-org/youtube-dl
synced 2024-11-27 02:16:51 +01:00
[external/FFmpeg] Fix and improve --ffmpeg-location handling
* pass YoutubeDL (FileDownloader) to FFmpegPostProcessor constructor * consolidate path search in FFmpegPostProcessor * make availability of FFmpegFD depend on existence of FFmpegPostProcessor * detect ffmpeg executable on instantiation of FFmpegFD * resolves #32735
This commit is contained in:
parent
d8f134a664
commit
21792b88b7
@ -18,6 +18,7 @@ from test.helper import (
|
|||||||
)
|
)
|
||||||
from youtube_dl import YoutubeDL
|
from youtube_dl import YoutubeDL
|
||||||
from youtube_dl.compat import (
|
from youtube_dl.compat import (
|
||||||
|
compat_contextlib_suppress,
|
||||||
compat_http_cookiejar_Cookie,
|
compat_http_cookiejar_Cookie,
|
||||||
compat_http_server,
|
compat_http_server,
|
||||||
compat_kwargs,
|
compat_kwargs,
|
||||||
@ -35,6 +36,9 @@ from youtube_dl.downloader.external import (
|
|||||||
HttpieFD,
|
HttpieFD,
|
||||||
WgetFD,
|
WgetFD,
|
||||||
)
|
)
|
||||||
|
from youtube_dl.postprocessor import (
|
||||||
|
FFmpegPostProcessor,
|
||||||
|
)
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
TEST_SIZE = 10 * 1024
|
TEST_SIZE = 10 * 1024
|
||||||
@ -227,7 +231,17 @@ class TestAria2cFD(unittest.TestCase):
|
|||||||
self.assertIn('--load-cookies=%s' % downloader._cookies_tempfile, cmd)
|
self.assertIn('--load-cookies=%s' % downloader._cookies_tempfile, cmd)
|
||||||
|
|
||||||
|
|
||||||
@ifExternalFDAvailable(FFmpegFD)
|
# Handle delegated availability
|
||||||
|
def ifFFmpegFDAvailable(externalFD):
|
||||||
|
# raise SkipTest, or set False!
|
||||||
|
avail = ifExternalFDAvailable(externalFD) and False
|
||||||
|
with compat_contextlib_suppress(Exception):
|
||||||
|
avail = FFmpegPostProcessor(downloader=None).available
|
||||||
|
return unittest.skipUnless(
|
||||||
|
avail, externalFD.get_basename() + ' not found')
|
||||||
|
|
||||||
|
|
||||||
|
@ifFFmpegFDAvailable(FFmpegFD)
|
||||||
class TestFFmpegFD(unittest.TestCase):
|
class TestFFmpegFD(unittest.TestCase):
|
||||||
_args = []
|
_args = []
|
||||||
|
|
||||||
|
@ -13,7 +13,12 @@ from ..compat import (
|
|||||||
compat_str,
|
compat_str,
|
||||||
compat_subprocess_Popen,
|
compat_subprocess_Popen,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
from ..postprocessor.ffmpeg import FFmpegPostProcessor, EXT_TO_OUT_FORMATS
|
from ..postprocessor.ffmpeg import FFmpegPostProcessor, EXT_TO_OUT_FORMATS
|
||||||
|
except ImportError:
|
||||||
|
FFmpegPostProcessor = None
|
||||||
|
|
||||||
from ..utils import (
|
from ..utils import (
|
||||||
cli_option,
|
cli_option,
|
||||||
cli_valueless_option,
|
cli_valueless_option,
|
||||||
@ -362,13 +367,14 @@ class FFmpegFD(ExternalFD):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def available(cls):
|
def available(cls):
|
||||||
return FFmpegPostProcessor().available
|
# actual availability can only be confirmed for an instance
|
||||||
|
return bool(FFmpegPostProcessor)
|
||||||
|
|
||||||
def _call_downloader(self, tmpfilename, info_dict):
|
def _call_downloader(self, tmpfilename, info_dict):
|
||||||
url = info_dict['url']
|
# `downloader` means the parent `YoutubeDL`
|
||||||
ffpp = FFmpegPostProcessor(downloader=self)
|
ffpp = FFmpegPostProcessor(downloader=self.ydl)
|
||||||
if not ffpp.available:
|
if not ffpp.available:
|
||||||
self.report_error('m3u8 download detected but ffmpeg or avconv could not be found. Please install one.')
|
self.report_error('ffmpeg required for download but no ffmpeg (nor avconv) executable could be found. Please install one.')
|
||||||
return False
|
return False
|
||||||
ffpp.check_version()
|
ffpp.check_version()
|
||||||
|
|
||||||
@ -397,6 +403,7 @@ class FFmpegFD(ExternalFD):
|
|||||||
# if end_time:
|
# if end_time:
|
||||||
# args += ['-t', compat_str(end_time - start_time)]
|
# args += ['-t', compat_str(end_time - start_time)]
|
||||||
|
|
||||||
|
url = info_dict['url']
|
||||||
cookies = self.ydl.cookiejar.get_cookies_for_url(url)
|
cookies = self.ydl.cookiejar.get_cookies_for_url(url)
|
||||||
if cookies:
|
if cookies:
|
||||||
args.extend(['-cookies', ''.join(
|
args.extend(['-cookies', ''.join(
|
||||||
|
@ -96,6 +96,7 @@ class FFmpegPostProcessor(PostProcessor):
|
|||||||
|
|
||||||
self._paths = None
|
self._paths = None
|
||||||
self._versions = None
|
self._versions = None
|
||||||
|
location = None
|
||||||
if self._downloader:
|
if self._downloader:
|
||||||
prefer_ffmpeg = self._downloader.params.get('prefer_ffmpeg', True)
|
prefer_ffmpeg = self._downloader.params.get('prefer_ffmpeg', True)
|
||||||
location = self._downloader.params.get('ffmpeg_location')
|
location = self._downloader.params.get('ffmpeg_location')
|
||||||
@ -118,32 +119,17 @@ class FFmpegPostProcessor(PostProcessor):
|
|||||||
location = os.path.dirname(os.path.abspath(location))
|
location = os.path.dirname(os.path.abspath(location))
|
||||||
if basename in ('ffmpeg', 'ffprobe'):
|
if basename in ('ffmpeg', 'ffprobe'):
|
||||||
prefer_ffmpeg = True
|
prefer_ffmpeg = True
|
||||||
|
|
||||||
self._paths = dict(
|
self._paths = dict(
|
||||||
(p, os.path.join(location, p)) for p in programs)
|
(p, p if location is None else os.path.join(location, p))
|
||||||
|
for p in programs)
|
||||||
self._versions = dict(
|
self._versions = dict(
|
||||||
|
x for x in (
|
||||||
(p, get_ffmpeg_version(self._paths[p])) for p in programs)
|
(p, get_ffmpeg_version(self._paths[p])) for p in programs)
|
||||||
if self._versions is None:
|
if x[1] is not None)
|
||||||
self._versions = dict(
|
|
||||||
(p, get_ffmpeg_version(p)) for p in programs)
|
|
||||||
self._paths = dict((p, p) for p in programs)
|
|
||||||
|
|
||||||
if prefer_ffmpeg is False:
|
for p in ('ffmpeg', 'avconv')[::-1 if prefer_ffmpeg is False else 1]:
|
||||||
prefs = ('avconv', 'ffmpeg')
|
if self._versions.get(p):
|
||||||
else:
|
self.basename = self.probe_basename = p
|
||||||
prefs = ('ffmpeg', 'avconv')
|
|
||||||
for p in prefs:
|
|
||||||
if self._versions[p]:
|
|
||||||
self.basename = p
|
|
||||||
break
|
|
||||||
|
|
||||||
if prefer_ffmpeg is False:
|
|
||||||
prefs = ('avprobe', 'ffprobe')
|
|
||||||
else:
|
|
||||||
prefs = ('ffprobe', 'avprobe')
|
|
||||||
for p in prefs:
|
|
||||||
if self._versions[p]:
|
|
||||||
self.probe_basename = p
|
|
||||||
break
|
break
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
Loading…
Reference in New Issue
Block a user