[cleanup] Remove RTSP and MMS support (#17030)

Authored by: seproDev
This commit is contained in:
sepro 2026-07-04 23:59:16 +02:00 committed by GitHub
parent 8c1f07d813
commit bed3d58c5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 29 additions and 125 deletions

View File

@ -245,7 +245,6 @@ The following provide support for impersonating browser requests. This may be re
### Deprecated ### Deprecated
* [**rtmpdump**](http://rtmpdump.mplayerhq.hu) - For downloading `rtmp` streams. ffmpeg can be used instead with `--downloader ffmpeg`. Licensed under [GPLv2+](http://rtmpdump.mplayerhq.hu) * [**rtmpdump**](http://rtmpdump.mplayerhq.hu) - For downloading `rtmp` streams. ffmpeg can be used instead with `--downloader ffmpeg`. Licensed under [GPLv2+](http://rtmpdump.mplayerhq.hu)
* [**mplayer**](http://mplayerhq.hu/design7/info.html) or [**mpv**](https://mpv.io) - For downloading `rstp`/`mms` streams. ffmpeg can be used instead with `--downloader ffmpeg`. Licensed under [GPLv2+](https://github.com/mpv-player/mpv/blob/master/Copyright)
To use or redistribute the dependencies, you must agree to their respective licensing terms. To use or redistribute the dependencies, you must agree to their respective licensing terms.
@ -625,16 +624,16 @@ Tip: Use `CTRL`+`F` (or `Command`+`F`) to search by keywords
"*10:15-inf" --download-sections "intro" "*10:15-inf" --download-sections "intro"
--downloader [PROTO:]NAME Name or path of the external downloader to --downloader [PROTO:]NAME Name or path of the external downloader to
use (optionally) prefixed by the protocols use (optionally) prefixed by the protocols
(http, ftp, m3u8, dash, rstp, rtmp, mms) to (http, ftp, m3u8, dash, rtmp) to use it for.
use it for. Currently supports native, Currently supports native, aria2c, axel,
aria2c, axel, curl, ffmpeg, httpie, wget. curl, ffmpeg, httpie, wget. You can use this
You can use this option multiple times to option multiple times to set different
set different downloaders for different downloaders for different protocols. E.g.
protocols. E.g. --downloader aria2c --downloader aria2c --downloader
--downloader "dash,m3u8:native" will use "dash,m3u8:native" will use aria2c for
aria2c for http/ftp downloads, and the http/ftp downloads, and the native
native downloader for dash/m3u8 downloads downloader for dash/m3u8 downloads (Alias:
(Alias: --external-downloader) --external-downloader)
--downloader-args NAME:ARGS Give these arguments to the external --downloader-args NAME:ARGS Give these arguments to the external
downloader. Specify the downloader name and downloader. Specify the downloader name and
the arguments separated by a colon ":". For the arguments separated by a colon ":". For
@ -1587,7 +1586,7 @@ Also filtering work for comparisons `=` (equals), `^=` (starts with), `$=` (ends
- `acodec`: Name of the audio codec in use - `acodec`: Name of the audio codec in use
- `vcodec`: Name of the video codec in use - `vcodec`: Name of the video codec in use
- `container`: Name of the container format - `container`: Name of the container format
- `protocol`: The protocol that will be used for the actual download, lower-case (`http`, `https`, `rtsp`, `rtmp`, `rtmpe`, `mms`, `f4m`, `ism`, `http_dash_segments`, `m3u8`, or `m3u8_native`) - `protocol`: The protocol that will be used for the actual download, lower-case (`http`, `https`, `rtmp`, `rtmpe`, `f4m`, `ism`, `http_dash_segments`, `m3u8`, or `m3u8_native`)
- `language`: Language code - `language`: Language code
- `dynamic_range`: The dynamic range of the video - `dynamic_range`: The dynamic range of the video
- `format_id`: A short description of the format - `format_id`: A short description of the format
@ -1615,7 +1614,7 @@ The available fields are:
- `lang`: The language preference as determined by the extractor (e.g. original language preferred over audio description) - `lang`: The language preference as determined by the extractor (e.g. original language preferred over audio description)
- `quality`: The quality of the format - `quality`: The quality of the format
- `source`: The preference of the source - `source`: The preference of the source
- `proto`: Protocol used for download (`https`/`ftps` > `http`/`ftp` > `m3u8_native`/`m3u8` > `http_dash_segments`> `websocket_frag` > `mms`/`rtsp` > `f4f`/`f4m`) - `proto`: Protocol used for download (`https`/`ftps` > `http`/`ftp` > `m3u8_native`/`m3u8` > `http_dash_segments`> `websocket_frag` > `f4f`/`f4m`)
- `vcodec`: Video Codec (`av01` > `vp9.2` > `vp9` > `h265` > `h264` > `vp8` > `h263` > `theora` > other) - `vcodec`: Video Codec (`av01` > `vp9.2` > `vp9` > `h265` > `h264` > `vp8` > `h263` > `theora` > other)
- `acodec`: Audio Codec (`flac`/`alac` > `wav`/`aiff` > `opus` > `vorbis` > `aac` > `mp4a` > `mp3` > `ac4` > `eac3` > `ac3` > `dts` > other) - `acodec`: Audio Codec (`flac`/`alac` > `wav`/`aiff` > `opus` > `vorbis` > `aac` > `mp4a` > `mp3` > `ac4` > `eac3` > `ac3` > `dts` > other)
- `codec`: Equivalent to `vcodec,acodec` - `codec`: Equivalent to `vcodec,acodec`

View File

@ -689,8 +689,6 @@ class TestUtil(unittest.TestCase):
self.assertEqual(url_or_none('//foo.de'), '//foo.de') self.assertEqual(url_or_none('//foo.de'), '//foo.de')
self.assertEqual(url_or_none('s3://foo.de'), None) self.assertEqual(url_or_none('s3://foo.de'), None)
self.assertEqual(url_or_none('rtmpte://foo.de'), 'rtmpte://foo.de') self.assertEqual(url_or_none('rtmpte://foo.de'), 'rtmpte://foo.de')
self.assertEqual(url_or_none('mms://foo.de'), 'mms://foo.de')
self.assertEqual(url_or_none('rtspu://foo.de'), 'rtspu://foo.de')
self.assertEqual(url_or_none('ftps://foo.de'), 'ftps://foo.de') self.assertEqual(url_or_none('ftps://foo.de'), 'ftps://foo.de')
self.assertEqual(url_or_none('ws://foo.de'), 'ws://foo.de') self.assertEqual(url_or_none('ws://foo.de'), 'ws://foo.de')
self.assertEqual(url_or_none('wss://foo.de'), 'wss://foo.de') self.assertEqual(url_or_none('wss://foo.de'), 'wss://foo.de')

View File

@ -480,7 +480,7 @@ class YoutubeDL:
geo_bypass_country geo_bypass_country
external_downloader: A dictionary of protocol keys and the executable of the external_downloader: A dictionary of protocol keys and the executable of the
external downloader to use for it. The allowed protocols external downloader to use for it. The allowed protocols
are default|http|ftp|m3u8|dash|rtsp|rtmp|mms. are default|http|ftp|m3u8|dash|rtmp.
Set the value to 'native' to use the native downloader Set the value to 'native' to use the native downloader
compat_opts: Compatibility options. See "Differences in default behavior". compat_opts: Compatibility options. See "Differences in default behavior".
The following options do not work when used through the API: The following options do not work when used through the API:

View File

@ -32,7 +32,6 @@ from .ism import IsmFD
from .mhtml import MhtmlFD from .mhtml import MhtmlFD
from .niconico import NiconicoLiveFD from .niconico import NiconicoLiveFD
from .rtmp import RtmpFD from .rtmp import RtmpFD
from .rtsp import RtspFD
from .websocket import WebSocketFragmentFD from .websocket import WebSocketFragmentFD
from .youtube_live_chat import YoutubeLiveChatFD from .youtube_live_chat import YoutubeLiveChatFD
from .bunnycdn import BunnyCdnFD from .bunnycdn import BunnyCdnFD
@ -44,8 +43,6 @@ PROTOCOL_MAP = {
'rtmp_ffmpeg': FFmpegFD, 'rtmp_ffmpeg': FFmpegFD,
'm3u8_native': HlsFD, 'm3u8_native': HlsFD,
'm3u8': FFmpegFD, 'm3u8': FFmpegFD,
'mms': RtspFD,
'rtsp': RtspFD,
'f4m': F4mFD, 'f4m': F4mFD,
'http_dash_segments': DashSegmentsFD, 'http_dash_segments': DashSegmentsFD,
'http_dash_segments_generator': DashSegmentsFD, 'http_dash_segments_generator': DashSegmentsFD,

View File

@ -375,7 +375,7 @@ class HttpieFD(ExternalFD):
class FFmpegFD(ExternalFD): class FFmpegFD(ExternalFD):
SUPPORTED_PROTOCOLS = ('http', 'https', 'ftp', 'ftps', 'm3u8', 'm3u8_native', 'rtsp', 'rtmp', 'rtmp_ffmpeg', 'mms', 'http_dash_segments') SUPPORTED_PROTOCOLS = ('http', 'https', 'ftp', 'ftps', 'm3u8', 'm3u8_native', 'rtmp', 'rtmp_ffmpeg', 'http_dash_segments')
SUPPORTED_FEATURES = (Features.TO_STDOUT, Features.MULTIPLE_FORMATS) SUPPORTED_FEATURES = (Features.TO_STDOUT, Features.MULTIPLE_FORMATS)
@classmethod @classmethod

View File

@ -1,42 +0,0 @@
import os
import subprocess
from .common import FileDownloader
from ..utils import check_executable
class RtspFD(FileDownloader):
def real_download(self, filename, info_dict):
url = info_dict['url']
self.report_destination(filename)
tmpfilename = self.temp_name(filename)
if check_executable('mplayer', ['-h']):
args = [
'mplayer', '-really-quiet', '-vo', 'null', '-vc', 'dummy',
'-dumpstream', '-dumpfile', tmpfilename, url]
elif check_executable('mpv', ['-h']):
args = [
'mpv', '-really-quiet', '--vo=null', '--stream-dump=' + tmpfilename, url]
else:
self.report_error('MMS or RTSP download detected but neither "mplayer" nor "mpv" could be run. Please install one')
return False
self._debug_cmd(args)
retval = subprocess.call(args)
if retval == 0:
fsize = os.path.getsize(tmpfilename)
self.to_screen(f'\r[{args[0]}] {fsize} bytes')
self.try_rename(tmpfilename, filename)
self._hook_progress({
'downloaded_bytes': fsize,
'total_bytes': fsize,
'filename': filename,
'status': 'finished',
}, info_dict)
return True
else:
self.to_stderr('\n')
self.report_error('%s exited with code %d' % (args[0], retval))
return False

View File

@ -359,7 +359,6 @@ from .commonmistakes import (
UnicodeBOMIE, UnicodeBOMIE,
) )
from .commonprotocols import ( from .commonprotocols import (
MmsIE,
RtmpIE, RtmpIE,
ViewSourceIE, ViewSourceIE,
) )

View File

@ -3542,7 +3542,7 @@ class InfoExtractor:
query = urllib.parse.urlparse(url).query query = urllib.parse.urlparse(url).query
url = re.sub(r'/(?:manifest|playlist|jwplayer)\.(?:m3u8|f4m|mpd|smil)', '', url) url = re.sub(r'/(?:manifest|playlist|jwplayer)\.(?:m3u8|f4m|mpd|smil)', '', url)
mobj = re.search( mobj = re.search(
r'(?:(?:http|rtmp|rtsp)(?P<s>s)?:)?(?P<url>//[^?]+)', url) r'(?:(?:http|rtmp)(?P<s>s)?:)?(?P<url>//[^?]+)', url)
url_base = mobj.group('url') url_base = mobj.group('url')
http_base_url = '{}{}:{}'.format('http', mobj.group('s') or '', url_base) http_base_url = '{}{}:{}'.format('http', mobj.group('s') or '', url_base)
formats = [] formats = []
@ -3567,27 +3567,15 @@ class InfoExtractor:
video_id, mpd_id='dash', fatal=False)) video_id, mpd_id='dash', fatal=False))
if re.search(r'(?:/smil:|\.smil)', url_base): if re.search(r'(?:/smil:|\.smil)', url_base):
if 'smil' not in skip_protocols: if 'smil' not in skip_protocols:
rtmp_formats = self._extract_smil_formats( formats.extend(self._extract_smil_formats(
manifest_url('jwplayer.smil'), manifest_url('jwplayer.smil'),
video_id, fatal=False) video_id, fatal=False))
for rtmp_format in rtmp_formats:
rtsp_format = rtmp_format.copy()
rtsp_format['url'] = '{}/{}'.format(rtmp_format['url'], rtmp_format['play_path'])
del rtsp_format['play_path']
del rtsp_format['ext']
rtsp_format.update({
'url': rtsp_format['url'].replace('rtmp://', 'rtsp://'),
'format_id': rtmp_format['format_id'].replace('rtmp', 'rtsp'),
'protocol': 'rtsp',
})
formats.extend([rtmp_format, rtsp_format])
else: else:
for protocol in ('rtmp', 'rtsp'): if 'rtmp' not in skip_protocols:
if protocol not in skip_protocols:
formats.append({ formats.append({
'url': f'{protocol}:{url_base}', 'url': f'rtmp:{url_base}',
'format_id': protocol, 'format_id': 'rtmp',
'protocol': protocol, 'protocol': 'rtmp',
}) })
return formats return formats

View File

@ -29,34 +29,6 @@ class RtmpIE(InfoExtractor):
} }
class MmsIE(InfoExtractor):
IE_DESC = False # Do not list
_VALID_URL = r'(?i)mms://.+'
_TEST = {
# Direct MMS link
'url': 'mms://kentro.kaist.ac.kr/200907/MilesReid(0709).wmv',
'info_dict': {
'id': 'MilesReid(0709)',
'ext': 'wmv',
'title': 'MilesReid(0709)',
},
'params': {
'skip_download': True, # rtsp downloads, requiring mplayer or mpv
},
}
def _real_extract(self, url):
video_id = self._generic_id(url)
title = self._generic_title(url)
return {
'id': video_id,
'title': title,
'url': url,
}
class ViewSourceIE(InfoExtractor): class ViewSourceIE(InfoExtractor):
IE_DESC = False IE_DESC = False
_VALID_URL = r'view-source:(?P<url>.+)' _VALID_URL = r'view-source:(?P<url>.+)'

View File

@ -138,7 +138,7 @@ class FilmOnChannelIE(InfoExtractor):
continue continue
if not is_live: if not is_live:
formats.extend(self._extract_wowza_formats( formats.extend(self._extract_wowza_formats(
stream_url, channel_id, skip_protocols=['dash', 'rtmp', 'rtsp'])) stream_url, channel_id, skip_protocols=['dash', 'rtmp']))
continue continue
quality = stream.get('quality') quality = stream.get('quality')
formats.append({ formats.append({

View File

@ -37,10 +37,7 @@ class MangomoloBaseIE(InfoExtractor):
m3u8_entry_protocol = 'm3u8' if self._IS_LIVE else 'm3u8_native' m3u8_entry_protocol = 'm3u8' if self._IS_LIVE else 'm3u8_native'
format_url = self._html_search_regex( format_url = self._html_search_regex(
[ r'(?:file|src)\s*:\s*"(https?://[^"]+?/playlist\.m3u8)', webpage, 'format url')
r'(?:file|src)\s*:\s*"(https?://[^"]+?/playlist\.m3u8)',
r'<a[^>]+href="(rtsp://[^"]+)"',
], webpage, 'format url')
formats = self._extract_wowza_formats( formats = self._extract_wowza_formats(
format_url, page_id, m3u8_entry_protocol, ['smil']) format_url, page_id, m3u8_entry_protocol, ['smil'])

View File

@ -1139,12 +1139,12 @@ def create_parser():
dest='external_downloader', metavar='[PROTO:]NAME', default={}, type='str', dest='external_downloader', metavar='[PROTO:]NAME', default={}, type='str',
action='callback', callback=_dict_from_options_callback, action='callback', callback=_dict_from_options_callback,
callback_kwargs={ callback_kwargs={
'allowed_keys': 'http|ftp|m3u8|dash|rtsp|rtmp|mms', 'allowed_keys': 'http|ftp|m3u8|dash|rtmp',
'default_key': 'default', 'default_key': 'default',
'process': str.strip, 'process': str.strip,
}, help=( }, help=(
'Name or path of the external downloader to use (optionally) prefixed by ' 'Name or path of the external downloader to use (optionally) prefixed by '
'the protocols (http, ftp, m3u8, dash, rstp, rtmp, mms) to use it for. ' 'the protocols (http, ftp, m3u8, dash, rtmp) to use it for. '
f'Currently supports native, {", ".join(sorted(list_external_downloaders()))}. ' f'Currently supports native, {", ".join(sorted(list_external_downloaders()))}. '
'You can use this option multiple times to set different downloaders for different protocols. ' 'You can use this option multiple times to set different downloaders for different protocols. '
'E.g. --downloader aria2c --downloader "dash,m3u8:native" will use ' 'E.g. --downloader aria2c --downloader "dash,m3u8:native" will use '

View File

@ -2076,7 +2076,7 @@ def url_or_none(url):
if not url or not isinstance(url, str): if not url or not isinstance(url, str):
return None return None
url = url.strip() url = url.strip()
return url if re.match(r'(?:(?:https?|rt(?:m(?:pt?[es]?|fp)|sp[su]?)|mms|ftps?|wss?):)?//', url) else None return url if re.match(r'(?:(?:https?|rtm(?:pt?[es]?|fp)|ftps?|wss?):)?//', url) else None
def strftime_or_none(timestamp, date_format='%Y%m%d', default=None): def strftime_or_none(timestamp, date_format='%Y%m%d', default=None):
@ -3195,10 +3195,6 @@ def determine_protocol(info_dict):
url = sanitize_url(info_dict['url']) url = sanitize_url(info_dict['url'])
if url.startswith('rtmp'): if url.startswith('rtmp'):
return 'rtmp' return 'rtmp'
elif url.startswith('mms'):
return 'mms'
elif url.startswith('rtsp'):
return 'rtsp'
ext = determine_ext(url) ext = determine_ext(url)
if ext == 'm3u8': if ext == 'm3u8':
@ -5373,7 +5369,7 @@ class FormatSorter:
'hdr': {'type': 'ordered', 'regex': True, 'field': 'dynamic_range', 'hdr': {'type': 'ordered', 'regex': True, 'field': 'dynamic_range',
'order': ['dv', '(hdr)?12', r'(hdr)?10\+', '(hdr)?10', 'hlg', '', 'sdr', None]}, 'order': ['dv', '(hdr)?12', r'(hdr)?10\+', '(hdr)?10', 'hlg', '', 'sdr', None]},
'proto': {'type': 'ordered', 'regex': True, 'field': 'protocol', 'proto': {'type': 'ordered', 'regex': True, 'field': 'protocol',
'order': ['(ht|f)tps', '(ht|f)tp$', 'm3u8.*', '.*dash', 'websocket_frag', 'rtmpe?', '', 'mms|rtsp', 'ws|websocket', 'f4']}, 'order': ['(ht|f)tps', '(ht|f)tp$', 'm3u8.*', '.*dash', 'websocket_frag', 'rtmpe?', '', 'ws|websocket', 'f4']},
'vext': {'type': 'ordered', 'field': 'video_ext', 'vext': {'type': 'ordered', 'field': 'video_ext',
'order': ('mp4', 'mov', 'webm', 'flv', '', 'none'), 'order': ('mp4', 'mov', 'webm', 'flv', '', 'none'),
'order_free': ('webm', 'mp4', 'mov', 'flv', '', 'none')}, 'order_free': ('webm', 'mp4', 'mov', 'flv', '', 'none')},