streamlink/tests/stream/test_dash.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

412 lines
18 KiB
Python
Raw Normal View History

2022-06-27 22:21:46 +02:00
from typing import List
from unittest.mock import ANY, Mock, call
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
2022-06-27 22:21:46 +02:00
import pytest
import requests_mock as rm
from lxml.etree import ParseError
2022-06-27 22:21:46 +02:00
from streamlink.exceptions import PluginError
from streamlink.session import Streamlink
2021-09-20 09:46:12 +02:00
from streamlink.stream.dash import DASHStream, DASHStreamWorker
from streamlink.stream.dash_manifest import MPD, MPDParsingError
from streamlink.utils.parse import parse_xml as original_parse_xml
from tests.resources import text, xml
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
class TestDASHStreamParseManifest:
@pytest.fixture(autouse=True)
def _response(self, request: pytest.FixtureRequest, requests_mock: rm.Mocker):
invalid = requests_mock.register_uri(rm.ANY, rm.ANY, exc=rm.exceptions.InvalidRequest("Invalid request"))
response = requests_mock.register_uri("GET", "http://test/manifest.mpd", **getattr(request, "param", {}))
called_once = "nomockedhttprequest" not in request.keywords
yield
assert not invalid.called
assert response.called_once is called_once
@pytest.fixture()
def parse_xml(self, monkeypatch: pytest.MonkeyPatch):
parse_xml = Mock(return_value=Mock())
monkeypatch.setattr("streamlink.stream.dash.parse_xml", parse_xml)
return parse_xml
@pytest.fixture()
def mpd(self, monkeypatch: pytest.MonkeyPatch, parse_xml: Mock):
mpd = Mock()
monkeypatch.setattr("streamlink.stream.dash.MPD", mpd)
return mpd
@pytest.mark.parametrize(("se_parse_xml", "se_mpd"), [
(ParseError, None),
(None, MPDParsingError),
])
def test_parse_fail(self, session: Streamlink, mpd: Mock, parse_xml: Mock, se_parse_xml, se_mpd):
parse_xml.side_effect = se_parse_xml
mpd.side_effect = se_mpd
with pytest.raises(PluginError) as cm:
DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert str(cm.value).startswith("Failed to parse MPD manifest: ")
def test_video_only(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=720),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-02-16 00:51:25 +01:00
assert sorted(streams.keys()) == sorted(["720p", "1080p"])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
def test_audio_only(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="audio/mp4", bandwidth=128.0, lang="en"),
Mock(id="2", contentProtections=None, mimeType="audio/mp4", bandwidth=256.0, lang="en"),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-02-16 00:51:25 +01:00
assert sorted(streams.keys()) == sorted(["a128k", "a256k"])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
def test_audio_single(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=720),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080),
Mock(id="3", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="en"),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-02-16 00:51:25 +01:00
assert sorted(streams.keys()) == sorted(["720p", "1080p"])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
def test_audio_multi(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=720),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080),
Mock(id="3", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="en"),
Mock(id="4", contentProtections=None, mimeType="audio/aac", bandwidth=256.0, lang="en"),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-02-16 00:51:25 +01:00
assert sorted(streams.keys()) == sorted(["720p+a128k", "1080p+a128k", "720p+a256k", "1080p+a256k"])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
def test_audio_multi_lang(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=720),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080),
Mock(id="3", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="en"),
Mock(id="4", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="es"),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-02-16 00:51:25 +01:00
assert sorted(streams.keys()) == sorted(["720p", "1080p"])
2023-03-24 14:22:33 +01:00
assert getattr(streams["720p"].audio_representation, "lang", None) == "en"
assert getattr(streams["1080p"].audio_representation, "lang", None) == "en"
def test_audio_multi_lang_alpha3(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=720),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080),
Mock(id="3", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="eng"),
Mock(id="4", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="spa"),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-02-16 00:51:25 +01:00
assert sorted(streams.keys()) == sorted(["720p", "1080p"])
2023-03-24 14:22:33 +01:00
assert getattr(streams["720p"].audio_representation, "lang", None) == "eng"
assert getattr(streams["1080p"].audio_representation, "lang", None) == "eng"
def test_audio_invalid_lang(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=720),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080),
Mock(id="3", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="en_no_voice"),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-02-16 00:51:25 +01:00
assert sorted(streams.keys()) == sorted(["720p", "1080p"])
2023-03-24 14:22:33 +01:00
assert getattr(streams["720p"].audio_representation, "lang", None) == "en_no_voice"
assert getattr(streams["1080p"].audio_representation, "lang", None) == "en_no_voice"
def test_audio_multi_lang_locale(self, monkeypatch: pytest.MonkeyPatch, session: Streamlink, mpd: Mock):
session.set_option("locale", "es_ES")
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=720),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080),
Mock(id="3", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="en"),
Mock(id="4", contentProtections=None, mimeType="audio/aac", bandwidth=128.0, lang="es"),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-02-16 00:51:25 +01:00
assert sorted(streams.keys()) == sorted(["720p", "1080p"])
2023-03-24 14:22:33 +01:00
assert getattr(streams["720p"].audio_representation, "lang", None) == "es"
assert getattr(streams["1080p"].audio_representation, "lang", None) == "es"
# Verify the fix for https://github.com/streamlink/streamlink/issues/3365
def test_duplicated_resolutions(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=1080, bandwidth=128.0),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080, bandwidth=64.0),
Mock(id="3", contentProtections=None, mimeType="video/mp4", height=1080, bandwidth=32.0),
Mock(id="4", contentProtections=None, mimeType="video/mp4", height=720),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
assert sorted(streams.keys()) == sorted(["720p", "1080p", "1080p_alt", "1080p_alt2"])
# Verify the fix for https://github.com/streamlink/streamlink/issues/4217
def test_duplicated_resolutions_sorted_bandwidth(self, session: Streamlink, mpd: Mock):
adaptationset = Mock(
contentProtections=None,
representations=[
Mock(id="1", contentProtections=None, mimeType="video/mp4", height=1080, bandwidth=64.0),
Mock(id="2", contentProtections=None, mimeType="video/mp4", height=1080, bandwidth=128.0),
Mock(id="3", contentProtections=None, mimeType="video/mp4", height=1080, bandwidth=32.0),
],
)
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
2023-03-24 14:22:33 +01:00
assert getattr(streams["1080p"].video_representation, "bandwidth", None) == pytest.approx(128.0)
assert getattr(streams["1080p_alt"].video_representation, "bandwidth", None) == pytest.approx(64.0)
assert getattr(streams["1080p_alt2"].video_representation, "bandwidth", None) == pytest.approx(32.0)
@pytest.mark.parametrize("adaptationset", [
pytest.param(
Mock(contentProtections="DRM", representations=[]),
id="ContentProtection on AdaptationSet",
),
pytest.param(
Mock(contentProtections=None, representations=[Mock(id="1", contentProtections="DRM")]),
id="ContentProtection on Representation",
),
])
def test_contentprotection(self, session: Streamlink, mpd: Mock, adaptationset: Mock):
mpd.return_value = Mock(periods=[Mock(adaptationSets=[adaptationset])])
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
2023-02-16 00:51:25 +01:00
with pytest.raises(PluginError):
DASHStream.parse_manifest(session, "http://test/manifest.mpd")
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
@pytest.mark.nomockedhttprequest()
def test_string(self, session: Streamlink, mpd: Mock, parse_xml: Mock):
with text("dash/test_9.mpd") as mpd_txt:
test_manifest = mpd_txt.read()
parse_xml.side_effect = original_parse_xml
mpd.side_effect = MPD
streams = DASHStream.parse_manifest(session, test_manifest)
assert mpd.call_args_list == [call(ANY)]
assert list(streams.keys()) == ["480p"]
# TODO: Move this test to test_dash_parser and properly test segment URLs.
# This test currently achieves nothing... (manifest fixture added in 7aada92)
def test_segments_number_time(self, session: Streamlink, mpd: Mock):
with xml("dash/test_9.mpd") as mpd_xml:
mpd.return_value = MPD(mpd_xml, base_url="http://test", url="http://test/manifest.mpd")
streams = DASHStream.parse_manifest(session, "http://test/manifest.mpd")
assert mpd.call_args_list == [call(ANY, url="http://test/manifest.mpd", base_url="http://test")]
assert list(streams.keys()) == ["480p"]
class TestDASHStreamOpen:
@pytest.fixture()
def reader(self, monkeypatch: pytest.MonkeyPatch):
reader = Mock()
monkeypatch.setattr("streamlink.stream.dash.DASHStreamReader", reader)
return reader
@pytest.fixture()
def muxer(self, monkeypatch: pytest.MonkeyPatch):
muxer = Mock()
monkeypatch.setattr("streamlink.stream.dash.FFMPEGMuxer", muxer)
return muxer
def test_stream_open_video_only(self, session: Streamlink, muxer: Mock, reader: Mock):
rep_video = Mock(ident=(None, None, "1"), mimeType="video/mp4")
stream = DASHStream(session, Mock(), rep_video)
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
stream.open()
assert reader.call_args_list == [call(stream, rep_video)]
reader_video = reader(stream, rep_video)
assert reader_video.open.called_once
assert muxer.call_args_list == []
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
def test_stream_open_video_audio(self, session: Streamlink, muxer: Mock, reader: Mock):
rep_video = Mock(ident=(None, None, "1"), mimeType="video/mp4")
rep_audio = Mock(ident=(None, None, "2"), mimeType="audio/mp3", lang="en")
stream = DASHStream(session, Mock(), rep_video, rep_audio)
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
stream.open()
assert reader.call_args_list == [call(stream, rep_video), call(stream, rep_audio)]
reader_video = reader(stream, rep_video)
reader_audio = reader(stream, rep_audio)
assert reader_video.open.called_once
assert reader_audio.open.called_once
assert muxer.call_args_list == [call(session, reader_video, reader_audio, copyts=True)]
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
2022-06-27 22:21:46 +02:00
class TestDASHStreamWorker:
@pytest.fixture()
def mock_time(self, monkeypatch: pytest.MonkeyPatch) -> Mock:
mock = Mock(return_value=1)
monkeypatch.setattr("streamlink.stream.dash.time", mock)
2022-06-27 22:21:46 +02:00
return mock
@pytest.fixture(autouse=True)
def mock_wait(self, monkeypatch: pytest.MonkeyPatch) -> Mock:
2022-06-27 22:21:46 +02:00
mock = Mock(return_value=True)
monkeypatch.setattr("streamlink.stream.dash.DASHStreamWorker.wait", mock)
2022-06-27 22:21:46 +02:00
return mock
@pytest.fixture()
def segments(self) -> List[Mock]:
return [
Mock(url="init_segment"),
Mock(url="first_segment"),
Mock(url="second_segment"),
]
@pytest.fixture()
def mpd(self) -> Mock:
representation = Mock(
ident=(None, None, "1"),
mimeType="video/mp4",
height=720,
)
adaptationset = Mock(
contentProtections=None,
representations=[representation],
)
period = Mock(
duration=Mock(total_seconds=Mock(return_value=0)),
adaptationSets=[adaptationset],
)
representation.period = period
2022-06-27 22:21:46 +02:00
return Mock(
publishTime=1,
minimumUpdatePeriod=Mock(total_seconds=Mock(return_value=0)),
periods=[period],
get_representation=Mock(return_value=representation),
2022-06-27 22:21:46 +02:00
)
@pytest.fixture()
def representation(self, mpd) -> Mock:
return mpd.periods[0].adaptationSets[0].representations[0]
2022-06-27 22:21:46 +02:00
@pytest.fixture()
def worker(self, mpd):
stream = Mock(mpd=mpd, period=0, args={})
reader = Mock(stream=stream, ident=(None, None, "1"))
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
worker = DASHStreamWorker(reader)
2022-06-27 22:21:46 +02:00
return worker
def test_dynamic_reload(
self,
monkeypatch: pytest.MonkeyPatch,
worker: DASHStreamWorker,
representation: Mock,
segments: List[Mock],
mpd: Mock,
):
mpd.dynamic = True
mpd.type = "dynamic"
monkeypatch.setattr("streamlink.stream.dash.MPD", lambda *args, **kwargs: mpd)
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
segment_iter = worker.iter_segments()
representation.segments.return_value = segments[:1]
2022-06-27 22:21:46 +02:00
assert next(segment_iter) is segments[0]
assert representation.segments.call_args_list == [call(init=True)]
assert not worker._wait.is_set()
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
2022-06-27 22:21:46 +02:00
representation.segments.reset_mock()
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
representation.segments.return_value = segments[1:]
2022-06-27 22:21:46 +02:00
assert [next(segment_iter), next(segment_iter)] == segments[1:]
assert representation.segments.call_args_list == [call(), call(init=False)]
assert not worker._wait.is_set()
2022-06-27 22:21:46 +02:00
def test_static(
self,
worker: DASHStreamWorker,
representation: Mock,
segments: List[Mock],
mpd: Mock,
):
mpd.dynamic = False
mpd.type = "static"
MPEG DASH Support (initial) (#1637) * stream.dash: parser for dash manifest files * stream.dash: stream player for dash with plugin to support dash:// prefixed urls * cli.main: make sure that streams are closed on errors * stream.dash: fix some parsing bugs * stream.dash: tidy up the segment number generation * plugins.dash: wip segment timeline * stream.dash: update to segment timeline parsing * stream.dash: py3 support * stream.dash: raise an error for DRM protected streams * stream.dash: fixes for timescaling and some segment templates * docs: add DASHStream to docs with other Stream classes * dash: fix for video only stream * plugins.dash: fix bug where all URLs were matched * stream.dash: fix issue with manifest reload * plugin.dash: add tests and fix a couple of bugs found in testing * stream.dash: add some tests to cover the DASHStream classes * WIP: audio only streams * add some debugging for threads and remove the thread joins * dash: startNumber should default to 1 * dash: follow redirects to get the base url * dash: fix bool parser, and segment template parser * dash: fixed some issues... ...with some segment templates, as well as improving the presentation delay handling * dash: add a back-off for checking for manifest changes * dash: fix broken tests * dash: incomplete support for Segment@r * dash: fixed audio/video sync issue Added a `copyts` option to the FFMPEG muxer class so that the timestamps given in the source files are maintained, this appears to fix the a/v sync issues. NB. The timestamp can get weird, but that's how it is :) * dash: support for Time _and_ Number in segment timeline * tests: add some dash parser tests + a little refactor * tests: add dash to built in plugins * tests: more coverage of dash_parser Added a new module for tests, `freezegun`, for mocking time. * dash: fix for missing publishTime * dash: update available_at times to be datetime This should fix any timezone or leap-second issues, etc. * fixed timing issue for 1tv.ru * dash: fix availability timeline for segment timeline * dash: flake8 tweaks * dash: add a few debug logging messages
2018-05-30 21:30:38 +02:00
representation.segments.return_value = segments
2022-06-27 22:21:46 +02:00
assert list(worker.iter_segments()) == segments
assert representation.segments.call_args_list == [call(init=True)]
assert worker._wait.is_set()
2022-06-27 22:21:46 +02:00
# Verify the fix for https://github.com/streamlink/streamlink/issues/2873
2022-06-27 22:21:46 +02:00
@pytest.mark.parametrize("duration", [
0,
204.32,
])
def test_static_refresh_wait(
self,
duration: float,
mock_wait: Mock,
2022-06-27 22:21:46 +02:00
mock_time: Mock,
worker: DASHStreamWorker,
representation: Mock,
segments: List[Mock],
mpd: Mock,
):
mpd.dynamic = False
mpd.type = "static"
mpd.periods[0].duration.total_seconds.return_value = duration
representation.segments.return_value = segments
assert list(worker.iter_segments()) == segments
assert representation.segments.call_args_list == [call(init=True)]
assert mock_wait.call_args_list == [call(5)]
assert worker._wait.is_set()