mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-15 13:43:04 +00:00
Compare commits
3 Commits
47cdc68e03
...
63e66cd0ad
Author | SHA1 | Date | |
---|---|---|---|
|
63e66cd0ad | ||
|
f2df407165 | ||
|
ca9def714a |
2
.github/ISSUE_TEMPLATE/1_broken_site.yml
vendored
2
.github/ISSUE_TEMPLATE/1_broken_site.yml
vendored
@ -32,7 +32,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
@ -44,7 +44,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
@ -40,7 +40,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/ISSUE_TEMPLATE/4_bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/4_bug_report.yml
vendored
@ -25,7 +25,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/ISSUE_TEMPLATE/5_feature_request.yml
vendored
2
.github/ISSUE_TEMPLATE/5_feature_request.yml
vendored
@ -23,7 +23,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/ISSUE_TEMPLATE/6_question.yml
vendored
2
.github/ISSUE_TEMPLATE/6_question.yml
vendored
@ -29,7 +29,7 @@ body:
|
|||||||
id: question
|
id: question
|
||||||
attributes:
|
attributes:
|
||||||
label: Please make sure the question is worded well enough to be understood
|
label: Please make sure the question is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information and as much context and examples as possible
|
placeholder: Provide any additional information and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
@ -32,7 +32,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
@ -44,7 +44,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
@ -40,7 +40,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/ISSUE_TEMPLATE_tmpl/4_bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE_tmpl/4_bug_report.yml
vendored
@ -25,7 +25,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
@ -23,7 +23,7 @@ body:
|
|||||||
id: description
|
id: description
|
||||||
attributes:
|
attributes:
|
||||||
label: Provide a description that is worded well enough to be understood
|
label: Provide a description that is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
placeholder: Provide any additional information, any suggested solutions, and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
2
.github/ISSUE_TEMPLATE_tmpl/6_question.yml
vendored
2
.github/ISSUE_TEMPLATE_tmpl/6_question.yml
vendored
@ -29,7 +29,7 @@ body:
|
|||||||
id: question
|
id: question
|
||||||
attributes:
|
attributes:
|
||||||
label: Please make sure the question is worded well enough to be understood
|
label: Please make sure the question is worded well enough to be understood
|
||||||
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/ytdl-org/youtube-dl#is-the-description-of-the-issue-itself-sufficient)
|
description: See [is-the-description-of-the-issue-itself-sufficient](https://github.com/yt-dlp/yt-dlp/blob/master/CONTRIBUTING.md#is-the-description-of-the-issue-itself-sufficient)
|
||||||
placeholder: Provide any additional information and as much context and examples as possible
|
placeholder: Provide any additional information and as much context and examples as possible
|
||||||
validations:
|
validations:
|
||||||
required: true
|
required: true
|
||||||
|
13
README.md
13
README.md
@ -147,7 +147,7 @@ Some of yt-dlp's default options are different from that of youtube-dl and youtu
|
|||||||
* Some private fields such as filenames are removed by default from the infojson. Use `--no-clean-infojson` or `--compat-options no-clean-infojson` to revert this
|
* Some private fields such as filenames are removed by default from the infojson. Use `--no-clean-infojson` or `--compat-options no-clean-infojson` to revert this
|
||||||
* When `--embed-subs` and `--write-subs` are used together, the subtitles are written to disk and also embedded in the media file. You can use just `--embed-subs` to embed the subs and automatically delete the separate file. See [#630 (comment)](https://github.com/yt-dlp/yt-dlp/issues/630#issuecomment-893659460) for more info. `--compat-options no-keep-subs` can be used to revert this
|
* When `--embed-subs` and `--write-subs` are used together, the subtitles are written to disk and also embedded in the media file. You can use just `--embed-subs` to embed the subs and automatically delete the separate file. See [#630 (comment)](https://github.com/yt-dlp/yt-dlp/issues/630#issuecomment-893659460) for more info. `--compat-options no-keep-subs` can be used to revert this
|
||||||
* `certifi` will be used for SSL root certificates, if installed. If you want to use system certificates (e.g. self-signed), use `--compat-options no-certifi`
|
* `certifi` will be used for SSL root certificates, if installed. If you want to use system certificates (e.g. self-signed), use `--compat-options no-certifi`
|
||||||
* youtube-dl tries to remove some superfluous punctuations from filenames. While this can sometimes be helpfull, it is often undesirable. So yt-dlp tries to keep the fields in the filenames as close to their original values as possible. You can use `--compat-options filename-sanitization` to revert to youtube-dl's behavior
|
* youtube-dl tries to remove some superfluous punctuations from filenames. While this can sometimes be helpful, it is often undesirable. So yt-dlp tries to keep the fields in the filenames as close to their original values as possible. You can use `--compat-options filename-sanitization` to revert to youtube-dl's behavior
|
||||||
|
|
||||||
For ease of use, a few more compat options are available:
|
For ease of use, a few more compat options are available:
|
||||||
|
|
||||||
@ -238,7 +238,7 @@ File|Description
|
|||||||
:---|:---
|
:---|:---
|
||||||
[yt-dlp](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp)|Platform-independent [zipimport](https://docs.python.org/3/library/zipimport.html) binary. Needs Python (recommended for **Linux/BSD**)
|
[yt-dlp](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp)|Platform-independent [zipimport](https://docs.python.org/3/library/zipimport.html) binary. Needs Python (recommended for **Linux/BSD**)
|
||||||
[yt-dlp.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe)|Windows (Win7 SP1+) standalone x64 binary (recommended for **Windows**)
|
[yt-dlp.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp.exe)|Windows (Win7 SP1+) standalone x64 binary (recommended for **Windows**)
|
||||||
[yt-dlp_macos](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos)|MacOS (10.15+) standalone executable (recommended for **MacOS**)
|
[yt-dlp_macos](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos)|Universal MacOS (10.15+) standalone executable (recommended for **MacOS**)
|
||||||
|
|
||||||
#### Alternatives
|
#### Alternatives
|
||||||
|
|
||||||
@ -246,8 +246,8 @@ File|Description
|
|||||||
:---|:---
|
:---|:---
|
||||||
[yt-dlp_x86.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_x86.exe)|Windows (Vista SP2+) standalone x86 (32-bit) binary
|
[yt-dlp_x86.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_x86.exe)|Windows (Vista SP2+) standalone x86 (32-bit) binary
|
||||||
[yt-dlp_min.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_min.exe)|Windows (Win7 SP1+) standalone x64 binary built with `py2exe`<br/> ([Not recommended](#standalone-py2exe-builds-windows))
|
[yt-dlp_min.exe](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_min.exe)|Windows (Win7 SP1+) standalone x64 binary built with `py2exe`<br/> ([Not recommended](#standalone-py2exe-builds-windows))
|
||||||
[yt-dlp_linux](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux)|UNIX standalone x64 binary
|
[yt-dlp_linux](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux)|Linux standalone x64 binary
|
||||||
[yt-dlp_linux.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux.zip)|Unpackaged Unix executable (no auto-update)
|
[yt-dlp_linux.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_linux.zip)|Unpackaged Linux executable (no auto-update)
|
||||||
[yt-dlp_win.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_win.zip)|Unpackaged Windows executable (no auto-update)
|
[yt-dlp_win.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_win.zip)|Unpackaged Windows executable (no auto-update)
|
||||||
[yt-dlp_macos.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos.zip)|Unpackaged MacOS (10.15+) executable (no auto-update)
|
[yt-dlp_macos.zip](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos.zip)|Unpackaged MacOS (10.15+) executable (no auto-update)
|
||||||
[yt-dlp_macos_legacy](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos_legacy)|MacOS (10.9+) standalone x64 executable
|
[yt-dlp_macos_legacy](https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp_macos_legacy)|MacOS (10.9+) standalone x64 executable
|
||||||
@ -305,7 +305,7 @@ While all the other dependencies are optional, `ffmpeg` and `ffprobe` are highly
|
|||||||
|
|
||||||
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.
|
||||||
|
|
||||||
The Windows and MacOS standalone release binaries are built with the Python interpreter and the packages marked with **\*** included.
|
The standalone release binaries are built with the Python interpreter and the packages marked with **\*** included.
|
||||||
|
|
||||||
If you do not have the necessary dependencies for a task you are attempting, yt-dlp will warn you. All the currently available dependencies are visible at the top of the `--verbose` output
|
If you do not have the necessary dependencies for a task you are attempting, yt-dlp will warn you. All the currently available dependencies are visible at the top of the `--verbose` output
|
||||||
|
|
||||||
@ -414,7 +414,8 @@ You can also fork the project on github and run your fork's [build workflow](.gi
|
|||||||
--no-wait-for-video Do not wait for scheduled streams (default)
|
--no-wait-for-video Do not wait for scheduled streams (default)
|
||||||
--mark-watched Mark videos watched (even with --simulate)
|
--mark-watched Mark videos watched (even with --simulate)
|
||||||
--no-mark-watched Do not mark videos watched (default)
|
--no-mark-watched Do not mark videos watched (default)
|
||||||
--no-colors Do not emit color codes in output
|
--no-colors Do not emit color codes in output (Alias:
|
||||||
|
--no-colours)
|
||||||
--compat-options OPTS Options that can help keep compatibility
|
--compat-options OPTS Options that can help keep compatibility
|
||||||
with youtube-dl or youtube-dlc
|
with youtube-dl or youtube-dlc
|
||||||
configurations by reverting some of the
|
configurations by reverting some of the
|
||||||
|
@ -1053,6 +1053,7 @@ class TestYoutubeDL(unittest.TestCase):
|
|||||||
for v in get_downloaded_info_dicts(params, entries)]
|
for v in get_downloaded_info_dicts(params, entries)]
|
||||||
self.assertEqual(results, list(enumerate(zip(expected_ids, expected_ids))), f'Entries of {name} for {params}')
|
self.assertEqual(results, list(enumerate(zip(expected_ids, expected_ids))), f'Entries of {name} for {params}')
|
||||||
self.assertEqual(sorted(evaluated), expected_eval, f'Evaluation of {name} for {params}')
|
self.assertEqual(sorted(evaluated), expected_eval, f'Evaluation of {name} for {params}')
|
||||||
|
|
||||||
test_selection({}, INDICES)
|
test_selection({}, INDICES)
|
||||||
test_selection({'playlistend': 20}, INDICES, True)
|
test_selection({'playlistend': 20}, INDICES, True)
|
||||||
test_selection({'playlistend': 2}, INDICES[:2])
|
test_selection({'playlistend': 2}, INDICES[:2])
|
||||||
|
@ -43,9 +43,11 @@ from .postprocessor import (
|
|||||||
FFmpegFixupTimestampPP,
|
FFmpegFixupTimestampPP,
|
||||||
FFmpegMergerPP,
|
FFmpegMergerPP,
|
||||||
FFmpegPostProcessor,
|
FFmpegPostProcessor,
|
||||||
|
FFmpegVideoConvertorPP,
|
||||||
MoveFilesAfterDownloadPP,
|
MoveFilesAfterDownloadPP,
|
||||||
get_postprocessor,
|
get_postprocessor,
|
||||||
)
|
)
|
||||||
|
from .postprocessor.ffmpeg import resolve_mapping as resolve_recode_mapping
|
||||||
from .update import detect_variant
|
from .update import detect_variant
|
||||||
from .utils import (
|
from .utils import (
|
||||||
DEFAULT_OUTTMPL,
|
DEFAULT_OUTTMPL,
|
||||||
@ -3181,22 +3183,23 @@ class YoutubeDL:
|
|||||||
self.report_warning(f'{vid}: {msg}. Install ffmpeg to fix this automatically')
|
self.report_warning(f'{vid}: {msg}. Install ffmpeg to fix this automatically')
|
||||||
|
|
||||||
stretched_ratio = info_dict.get('stretched_ratio')
|
stretched_ratio = info_dict.get('stretched_ratio')
|
||||||
ffmpeg_fixup(
|
ffmpeg_fixup(stretched_ratio not in (1, None),
|
||||||
stretched_ratio not in (1, None),
|
|
||||||
f'Non-uniform pixel ratio {stretched_ratio}',
|
f'Non-uniform pixel ratio {stretched_ratio}',
|
||||||
FFmpegFixupStretchedPP)
|
FFmpegFixupStretchedPP)
|
||||||
|
|
||||||
ffmpeg_fixup(
|
|
||||||
(info_dict.get('requested_formats') is None
|
|
||||||
and info_dict.get('container') == 'm4a_dash'
|
|
||||||
and info_dict.get('ext') == 'm4a'),
|
|
||||||
'writing DASH m4a. Only some players support this container',
|
|
||||||
FFmpegFixupM4aPP)
|
|
||||||
|
|
||||||
downloader = get_suitable_downloader(info_dict, self.params) if 'protocol' in info_dict else None
|
downloader = get_suitable_downloader(info_dict, self.params) if 'protocol' in info_dict else None
|
||||||
downloader = downloader.FD_NAME if downloader else None
|
downloader = downloader.FD_NAME if downloader else None
|
||||||
|
|
||||||
if info_dict.get('requested_formats') is None: # Not necessary if doing merger
|
ext = info_dict.get('ext')
|
||||||
|
postprocessed_by_ffmpeg = info_dict.get('requested_formats') or any((
|
||||||
|
isinstance(pp, FFmpegVideoConvertorPP)
|
||||||
|
and resolve_recode_mapping(ext, pp.mapping)[0] not in (ext, None)
|
||||||
|
) for pp in self._pps['post_process'])
|
||||||
|
|
||||||
|
if not postprocessed_by_ffmpeg:
|
||||||
|
ffmpeg_fixup(ext == 'm4a' and info_dict.get('container') == 'm4a_dash',
|
||||||
|
'writing DASH m4a. Only some players support this container',
|
||||||
|
FFmpegFixupM4aPP)
|
||||||
ffmpeg_fixup(downloader == 'hlsnative' and not self.params.get('hls_use_mpegts')
|
ffmpeg_fixup(downloader == 'hlsnative' and not self.params.get('hls_use_mpegts')
|
||||||
or info_dict.get('is_live') and self.params.get('hls_use_mpegts') is None,
|
or info_dict.get('is_live') and self.params.get('hls_use_mpegts') is None,
|
||||||
'Possible MPEG-TS in MP4 container or malformed AAC timestamps',
|
'Possible MPEG-TS in MP4 container or malformed AAC timestamps',
|
||||||
|
@ -2,6 +2,7 @@ f'You are using an unsupported version of Python. Only Python versions 3.6 and a
|
|||||||
|
|
||||||
__license__ = 'Public Domain'
|
__license__ = 'Public Domain'
|
||||||
|
|
||||||
|
import collections
|
||||||
import getpass
|
import getpass
|
||||||
import itertools
|
import itertools
|
||||||
import optparse
|
import optparse
|
||||||
@ -516,7 +517,7 @@ def validate_options(opts):
|
|||||||
# Do not unnecessarily download audio
|
# Do not unnecessarily download audio
|
||||||
opts.format = 'bestaudio/best'
|
opts.format = 'bestaudio/best'
|
||||||
|
|
||||||
if opts.getcomments and opts.writeinfojson is None:
|
if opts.getcomments and opts.writeinfojson is None and not opts.embed_infojson:
|
||||||
# If JSON is not printed anywhere, but comments are requested, save it to file
|
# If JSON is not printed anywhere, but comments are requested, save it to file
|
||||||
if not opts.dumpjson or opts.print_json or opts.dump_single_json:
|
if not opts.dumpjson or opts.print_json or opts.dump_single_json:
|
||||||
opts.writeinfojson = True
|
opts.writeinfojson = True
|
||||||
@ -665,8 +666,11 @@ def get_postprocessors(opts):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ParsedOptions = collections.namedtuple('ParsedOptions', ('parser', 'options', 'urls', 'ydl_opts'))
|
||||||
|
|
||||||
|
|
||||||
def parse_options(argv=None):
|
def parse_options(argv=None):
|
||||||
""" @returns (parser, opts, urls, ydl_opts) """
|
"""@returns ParsedOptions(parser, opts, urls, ydl_opts)"""
|
||||||
parser, opts, urls = parseOpts(argv)
|
parser, opts, urls = parseOpts(argv)
|
||||||
urls = get_urls(urls, opts.batchfile, opts.verbose)
|
urls = get_urls(urls, opts.batchfile, opts.verbose)
|
||||||
|
|
||||||
@ -690,7 +694,7 @@ def parse_options(argv=None):
|
|||||||
else opts.audioformat if (opts.extractaudio and opts.audioformat in FFmpegExtractAudioPP.SUPPORTED_EXTS)
|
else opts.audioformat if (opts.extractaudio and opts.audioformat in FFmpegExtractAudioPP.SUPPORTED_EXTS)
|
||||||
else None)
|
else None)
|
||||||
|
|
||||||
return parser, opts, urls, {
|
return ParsedOptions(parser, opts, urls, {
|
||||||
'usenetrc': opts.usenetrc,
|
'usenetrc': opts.usenetrc,
|
||||||
'netrc_location': opts.netrc_location,
|
'netrc_location': opts.netrc_location,
|
||||||
'username': opts.username,
|
'username': opts.username,
|
||||||
@ -863,7 +867,7 @@ def parse_options(argv=None):
|
|||||||
'_warnings': warnings,
|
'_warnings': warnings,
|
||||||
'_deprecation_warnings': deprecation_warnings,
|
'_deprecation_warnings': deprecation_warnings,
|
||||||
'compat_opts': opts.compat_opts,
|
'compat_opts': opts.compat_opts,
|
||||||
}
|
})
|
||||||
|
|
||||||
|
|
||||||
def _real_main(argv=None):
|
def _real_main(argv=None):
|
||||||
|
@ -830,6 +830,7 @@ from .linkedin import (
|
|||||||
LinkedInLearningCourseIE,
|
LinkedInLearningCourseIE,
|
||||||
)
|
)
|
||||||
from .linuxacademy import LinuxAcademyIE
|
from .linuxacademy import LinuxAcademyIE
|
||||||
|
from .liputan6 import Liputan6IE
|
||||||
from .litv import LiTVIE
|
from .litv import LiTVIE
|
||||||
from .livejournal import LiveJournalIE
|
from .livejournal import LiveJournalIE
|
||||||
from .livestream import (
|
from .livestream import (
|
||||||
|
64
yt_dlp/extractor/liputan6.py
Normal file
64
yt_dlp/extractor/liputan6.py
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
from .common import InfoExtractor
|
||||||
|
from .vidio import VidioIE
|
||||||
|
|
||||||
|
|
||||||
|
class Liputan6IE(InfoExtractor):
|
||||||
|
_VALID_URL = r'https?://www\.liputan6\.com/\w+/read/\d+/(?P<id>[\w-]+)'
|
||||||
|
_TESTS = [{
|
||||||
|
'url': 'https://www.liputan6.com/news/read/5007510/video-duh-perawat-rs-di-medan-diduga-salah-berikan-obat-ke-pasien',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '7082548',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'Duh, Perawat RS di Medan Diduga Salah Berikan Obat Ke Pasien',
|
||||||
|
'thumbnail': 'https://thumbor.prod.vidiocdn.com/lOz5pStm9X-jjlTa_VQQUelOPtw=/640x360/filters:quality(70)/vidio-web-prod-video/uploads/video/image/7082548/duh-perawat-rs-di-medan-diduga-salah-berikan-obat-ke-pasien-ca1125.jpg',
|
||||||
|
'channel_id': '185693',
|
||||||
|
'uploader': 'Liputan6.com',
|
||||||
|
'duration': 104,
|
||||||
|
'uploader_url': 'https://www.vidio.com/@liputan6',
|
||||||
|
'description': 'md5:3b58ecff10ec3a41d4304cf98228435a',
|
||||||
|
'timestamp': 1657159427,
|
||||||
|
'uploader_id': 'liputan6',
|
||||||
|
'display_id': 'video-duh-perawat-rs-di-medan-diduga-salah-berikan-obat-ke-pasien',
|
||||||
|
'like_count': int,
|
||||||
|
'view_count': int,
|
||||||
|
'comment_count': int,
|
||||||
|
'tags': ['perawat indonesia', 'rumah sakit', 'Medan', 'viral hari ini', 'viral', 'enamplus'],
|
||||||
|
'channel': 'Default Channel',
|
||||||
|
'dislike_count': int,
|
||||||
|
'upload_date': '20220707'
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'url': 'https://www.liputan6.com/tv/read/5007719/video-program-minyakita-minyak-goreng-kemasan-sederhana-seharga-rp-14-ribu',
|
||||||
|
'info_dict': {
|
||||||
|
'id': '7082543',
|
||||||
|
'ext': 'mp4',
|
||||||
|
'title': 'md5:ecb7b3c598b97798bfd0eb50c6233b8c',
|
||||||
|
'channel_id': '604054',
|
||||||
|
'dislike_count': int,
|
||||||
|
'comment_count': int,
|
||||||
|
'timestamp': 1657159211,
|
||||||
|
'upload_date': '20220707',
|
||||||
|
'tags': ['minyakita', 'minyak goreng', 'liputan 6', 'sctv'],
|
||||||
|
'uploader_url': 'https://www.vidio.com/@sctv',
|
||||||
|
'display_id': 'video-program-minyakita-minyak-goreng-kemasan-sederhana-seharga-rp-14-ribu',
|
||||||
|
'like_count': int,
|
||||||
|
'uploader': 'SCTV',
|
||||||
|
'description': 'md5:6c374d82589b71fb98b3d550edb6873f',
|
||||||
|
'duration': 99,
|
||||||
|
'uploader_id': 'sctv',
|
||||||
|
'thumbnail': 'https://thumbor.prod.vidiocdn.com/AAIOjz-64hKojjdw5hr0oNNEeJg=/640x360/filters:quality(70)/vidio-web-prod-video/uploads/video/image/7082543/program-minyakita-minyak-goreng-kemasan-sederhana-seharga-rp14-ribu-_-liputan-6-7d9fbb.jpg',
|
||||||
|
'channel': 'Liputan 6 Pagi',
|
||||||
|
'view_count': int,
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
|
||||||
|
def _real_extract(self, url):
|
||||||
|
display_id = self._match_id(url)
|
||||||
|
webpage = self._download_webpage(url, display_id)
|
||||||
|
|
||||||
|
json_data = self._search_json(
|
||||||
|
r'window.kmklabs.gtm\s*=\s*', webpage, 'json_data', display_id)
|
||||||
|
video_id = json_data['videos']['video_1']['video_id']
|
||||||
|
|
||||||
|
return self.url_result(
|
||||||
|
f'https://www.vidio.com/watch/{video_id}-{display_id}', ie=VidioIE, video_id=display_id)
|
@ -428,9 +428,9 @@ def create_parser():
|
|||||||
action='store_false', dest='mark_watched',
|
action='store_false', dest='mark_watched',
|
||||||
help='Do not mark videos watched (default)')
|
help='Do not mark videos watched (default)')
|
||||||
general.add_option(
|
general.add_option(
|
||||||
'--no-colors',
|
'--no-colors', '--no-colours',
|
||||||
action='store_true', dest='no_color', default=False,
|
action='store_true', dest='no_color', default=False,
|
||||||
help='Do not emit color codes in output')
|
help='Do not emit color codes in output (Alias: --no-colours)')
|
||||||
general.add_option(
|
general.add_option(
|
||||||
'--compat-options',
|
'--compat-options',
|
||||||
metavar='OPTS', dest='compat_opts', default=set(), type='str',
|
metavar='OPTS', dest='compat_opts', default=set(), type='str',
|
||||||
|
@ -725,11 +725,10 @@ class FFmpegMetadataPP(FFmpegPostProcessor):
|
|||||||
value = value.replace('\0', '') # nul character cannot be passed in command line
|
value = value.replace('\0', '') # nul character cannot be passed in command line
|
||||||
metadata['common'].update({meta_f: value for meta_f in variadic(meta_list)})
|
metadata['common'].update({meta_f: value for meta_f in variadic(meta_list)})
|
||||||
|
|
||||||
# See [1-4] for some info on media metadata/metadata supported
|
# Info on media metadata/metadata supported by ffmpeg:
|
||||||
# by ffmpeg.
|
# https://wiki.multimedia.cx/index.php/FFmpeg_Metadata
|
||||||
# 1. https://kdenlive.org/en/project/adding-meta-data-to-mp4-video/
|
# https://kdenlive.org/en/project/adding-meta-data-to-mp4-video/
|
||||||
# 2. https://wiki.multimedia.cx/index.php/FFmpeg_Metadata
|
# https://kodi.wiki/view/Video_file_tagging
|
||||||
# 3. https://kodi.wiki/view/Video_file_tagging
|
|
||||||
|
|
||||||
add('title', ('track', 'title'))
|
add('title', ('track', 'title'))
|
||||||
add('date', 'upload_date')
|
add('date', 'upload_date')
|
||||||
|
@ -1908,6 +1908,10 @@ class DateRange:
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{self.start.isoformat()} - {self.end.isoformat()}'
|
return f'{self.start.isoformat()} - {self.end.isoformat()}'
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return (isinstance(other, DateRange)
|
||||||
|
and self.start == other.start and self.end == other.end)
|
||||||
|
|
||||||
|
|
||||||
def platform_name():
|
def platform_name():
|
||||||
""" Returns the platform name as a str """
|
""" Returns the platform name as a str """
|
||||||
@ -2660,7 +2664,7 @@ class LazyList(collections.abc.Sequence):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _reverse_index(x):
|
def _reverse_index(x):
|
||||||
return None if x is None else -(x + 1)
|
return None if x is None else ~x
|
||||||
|
|
||||||
def __getitem__(self, idx):
|
def __getitem__(self, idx):
|
||||||
if isinstance(idx, slice):
|
if isinstance(idx, slice):
|
||||||
@ -3662,21 +3666,26 @@ def match_filter_func(filters):
|
|||||||
return _match_func
|
return _match_func
|
||||||
|
|
||||||
|
|
||||||
def download_range_func(chapters, ranges):
|
class download_range_func:
|
||||||
def inner(info_dict, ydl):
|
def __init__(self, chapters, ranges):
|
||||||
|
self.chapters, self.ranges = chapters, ranges
|
||||||
|
|
||||||
|
def __call__(self, info_dict, ydl):
|
||||||
warning = ('There are no chapters matching the regex' if info_dict.get('chapters')
|
warning = ('There are no chapters matching the regex' if info_dict.get('chapters')
|
||||||
else 'Cannot match chapters since chapter information is unavailable')
|
else 'Cannot match chapters since chapter information is unavailable')
|
||||||
for regex in chapters or []:
|
for regex in self.chapters or []:
|
||||||
for i, chapter in enumerate(info_dict.get('chapters') or []):
|
for i, chapter in enumerate(info_dict.get('chapters') or []):
|
||||||
if re.search(regex, chapter['title']):
|
if re.search(regex, chapter['title']):
|
||||||
warning = None
|
warning = None
|
||||||
yield {**chapter, 'index': i}
|
yield {**chapter, 'index': i}
|
||||||
if chapters and warning:
|
if self.chapters and warning:
|
||||||
ydl.to_screen(f'[info] {info_dict["id"]}: {warning}')
|
ydl.to_screen(f'[info] {info_dict["id"]}: {warning}')
|
||||||
|
|
||||||
yield from ({'start_time': start, 'end_time': end} for start, end in ranges or [])
|
yield from ({'start_time': start, 'end_time': end} for start, end in self.ranges or [])
|
||||||
|
|
||||||
return inner
|
def __eq__(self, other):
|
||||||
|
return (isinstance(other, download_range_func)
|
||||||
|
and self.chapters == other.chapters and self.ranges == other.ranges)
|
||||||
|
|
||||||
|
|
||||||
def parse_dfxp_time_expr(time_expr):
|
def parse_dfxp_time_expr(time_expr):
|
||||||
|
Loading…
Reference in New Issue
Block a user