Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 27b3693

Browse files
committed
docs(changelog): Add v3.0.0 changes
1 parent 9aeab18 commit 27b3693

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

CHANGELOG.md

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,221 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [3.0.0] - 2024-03-01
9+
10+
### Added
11+
12+
- Support for Python 3.12.
13+
- Audio track's Codec Enum now has [FLAC](https://en.wikipedia.org/wiki/FLAC) defined.
14+
- The Downloader to use can now be set in the config under the [downloader key](CONFIG.md#downloader-str).
15+
- New Multi-Threaded Downloader, `requests`, that makes HTTP(S) calls using [Python-requests](https://requests.readthedocs.io).
16+
- New Multi-Threaded Downloader, `curl_impersonate`, that makes HTTP(S) calls using [Curl-Impersonate](https://github.com/yifeikong/curl-impersonate) via [Curl_CFFI](https://github.com/yifeikong/curl_cffi).
17+
- HLS manifests specifying a Byte range value without starting offsets are now supported.
18+
- HLS segments that use `EXT-X-DISCONTINUITY` are now supported.
19+
- DASH manifests with SegmentBase or only BaseURL are now supported.
20+
- Subtitle tracks from DASH manifests now automatically marked as SDH if `urn:tva:metadata:cs:AudioPurposeCS:2007 = 2`.
21+
- The `--audio-only/--subs-only/--chapters-only` flags can now be used simultaneously. For example, `--subs-only`
22+
with `--chapters-only` will get just Subtitles and Chapters.
23+
- Added `--video-only` flag, which can also still be simultaneously used with the only "only" flags. Using all four
24+
of these flags will have the same effect as not using any of them.
25+
- Added `--no-proxy` flag, disabling all uses of proxies, even if `--proxy` is set.
26+
- Added `--sub-format` option, which sets the wanted output subtitle format, defaulting to SubRip (SRT).
27+
- Added `Subtitle.reverse_rtl()` method to use SubtitleEdit's `/ReverseRtlStartEnd` functionality.
28+
- Added `Subtitle.convert()` method to convert the loaded Subtitle to another format. Note that you cannot convert to
29+
fTTML or fVTT, but you can convert from them. SubtitleEdit will be used in precedence over pycaption if available.
30+
Converting to SubStationAlphav4 requires SubtitleEdit, but you may want to manually alter the Canvas resolution after
31+
the download.
32+
- Added support for SubRip (SRT) format subtitles in `Subtitle.parse()` via pycaption.
33+
- Added `API` Vault Client aiming for a RESTful like API.
34+
- Added `Chapters` Class to hold the new reworked `Chapter` objects, automatically handling stuff like order of the
35+
Chapters, Chapter numbers, loading from a chapter file or string, and saving to a chapter file or string.
36+
- Added new `chapter_fallback_name` config option allowing you to set a Chapter Name Template used when muxing Chapters
37+
into an MKV Container with MKVMerge. Do note, it defaults to no Chapter Fallback Name at all, but MKVMerge will force
38+
`Chapter {i:02}` at least for me on Windows with the program language set to English. You may want to instead use
39+
`Chapter {j:02}` which will do `Chapter 01, Intro, Chapter 02` instead of `Chapter 01, Intro, Chapter 03` (an Intro
40+
is not a Chapter of story, but it is the 2nd Chapter marker, so It's up to you how you want to interpret it).
41+
- Added new `Track.OnSegmentDownloaded` Event, called any time one of the Track's segments were downloaded.
42+
- Added new `Subtitle.OnConverted` Event, called any time that Subtitle is converted.
43+
- Implemented `__add__` method to `Tracks` class, allowing you to add to the first Tracks object. For example, making
44+
it handy to merge HLS video tracks with DASH tracks, `tracks = dash_tracks + hls_tracks.videos`, or for iterating:
45+
`for track in dash.videos + hls.videos: ...`.
46+
- Added new utility `get_free_port()` to get a free local port to use, though it may be taken by the time it's used.
47+
48+
### Changed
49+
50+
- Moved from my forked release of pymp4 (`rlaphoenix-pymp4`) back to the original `pymp4` release as it is
51+
now up-to-date with some of my needed fixes.
52+
- The DASH manifest is now stored in the Track `url` property to be reused by `DASH.download_track()`.
53+
- Encrypted DASH streams are now downloaded in full and then decrypted, instead of downloading and decrypting
54+
each individual segment. Unlike HLS, DASH cannot dynamically switch out the DRM/Protection information.
55+
This brings both CPU and Disk IOPS improvements, as well as fixing rare weird decryption anomalies like broken
56+
or odd timestamps, decryption failures, or broken a/v continuity.
57+
- When a track is being decrypted, it now displays "Decrypting" and afterward "Decrypted" in place of the download
58+
speed.
59+
- When a track finishes downloaded, it now displays "Downloaded" in place of the download speed.
60+
- When licensing is needed and fails, the track will display "FAILED" in place of the download speed. The track
61+
download will cancel and all other track downloads will be skipped/cancelled; downloading will end.
62+
- The fancy smart quotes (`` and ``) are now stripped from filenames.
63+
- All available services are now listed if you provide an invalid service tag/alias.
64+
- If a WVD file fails to load and looks to be in the older unsupported v1 format, then instructions on migrating to
65+
v2 will be displayed.
66+
- If Shaka-Packager prints an error (i.e., `:ERROR:` log message) it will now raise a `subprocess.CalledProcessError`
67+
exception, even if the process return code is 0.
68+
- The Video classes' Primaries, Transfer, and Matrix classes had changes to their enum names to better represent their
69+
values and uses. See the changed names in the [commit](https://github.com/devine-dl/devine/commit/c159672181ee3bd07b06612f256fa8590d61795c).
70+
- SubRip (SRT) Subtitles no longer have the `MULTI-LANGUAGE SRT` header forcefully removed. The root cause of the error
71+
was identified and fixed in this release.
72+
- Since `Range.Transfer.SDR_BT_601_625 = 5` has been removed, `Range.from_cicp()` now internally remaps CICP transfer
73+
values of `5` to `6` (which is now `Range.Transfer.BT_601 = 6`).
74+
- Referer and User-Agent Header values passed to the aria2(c) downloader is now set via the dedicated `--referer` and
75+
`--user-agent` options respectively, instead of `--header`.
76+
- The aria2(c) `-j`, `-x`, and `-s` option values can now be set by the config under the `aria2c` key in the options'
77+
full names.
78+
- The aria2(c) `-x`, and `-s` option values now use aria2(c)'s own default values for them instead of `16`. The `j`
79+
option value defaults to ThreadPoolExecutor's algorithm of `min(32,(cpu_count+4))`.
80+
- The download progress bar now states `LICENSING` on the speed text when licensing DRM, and `LICENSED` once finished.
81+
- The download progress bar now states `CANCELLING`/`CANCELLED` on the speed text when cancelling downloads. This is to
82+
make it more clear that it didn't just stop, but stopped as it was cancelled.
83+
- The download cancel/skip events were moved to `constants.py` so it can be used across the codebase easier without
84+
argument drilling. `DL_POOL_STOP` was renamed to `DOWNLOAD_CANCELLED` and `DL_POOL_SKIP` to `DOWNLOAD_LICENCE_ONLY`.
85+
- The Cookie header is now calculated for each URL passed to the aria2(c) downloader based on the URL. Instead of
86+
passing every single cookie, which could have two cookies with the same name aimed for different host names, we now
87+
pass only cookies intended for the URL.
88+
- The aria2(c) process no longer prints output to the terminal directly. Devine now only prints contents of the
89+
captured log messages to the terminal. This allows filtering out of errors and warnings that isn't a problem.
90+
- DASH and HLS no longer download segments silencing errors on all but the last retry as the downloader rework makes
91+
this unnecessary. The errors will only be printed on the final retry regardless.
92+
- `Track.repackage()` now saves as `{name}_repack.{ext}` instead of `{name}.repack.{ext}`.
93+
- `Video.change_color_range()` now saves as `{name}_{limited|full}_range.{ext}` instead of `{name}.range{0|1}.{ext}`.
94+
- `Widevine.decrypt()` now saves as `{name}_decrypted.{ext}` instead of `{name}.decrypted.{ext}`.
95+
- Files starting with the save path's name and using the save path's extension, but not the save path, are no longer
96+
deleted on download finish/stop/failure.
97+
- The output container format is now explicitly specified as `MP4` when calling `shaka-packager`.
98+
- The default downloader is now `requests` instead of `aria2c` to reduce required external dependencies.
99+
- Reworked the `Chapter` class to only hold a timestamp and name value with an ID automatically generated as a CRC32 of
100+
the Chapter representation.
101+
- The `--group` option has been renamed to `--tag`.
102+
- The config file is now read from three more locations in the following order:
103+
1) The Devine Namespace Folder (e.g., `%appdata%/Python/Python311/site-packages/devine/devine.yaml`).
104+
2) The Parent Folder to the Devine Namespace Folder (e.g., `%appdata%/Python/Python311/site-packages/devine.yaml`).
105+
3) The AppDirs User Config Folder (e.g., `%localappdata%/devine/devine.yaml`).
106+
Location 2 allows having a config at the root of a portable folder.
107+
- An empty config file is no longer created when no config file is found.
108+
- You can now set a default cookie file for a Service, [see README](README.md#cookies--credentials).
109+
- You can now set a default credential for a Service, [see config](CONFIG.md#credentials-dictstr-strlistdict).
110+
- Services are now auth-less by default and the error for not having at least a cookie or credential is removed.
111+
Cookies/Credentials will only be loaded if a default one for the service is available, or if you use `-p/--profile`
112+
and the profile exists.
113+
- Subtitles when converting to SubRip (SRT) via SubtitleEdit will now use the `/ConvertColorsToDialog` option.
114+
- HLS segments are now merged by discontinuity instead of all at once. The merged discontinuities are then finally
115+
merged to one file using `ffmpeg`. Doing the final merge by byte concatenation did not work for some playlists.
116+
- The Track is no longer passed through Event Callables. If you are able to set a function on an Even Callable, then
117+
you should have access to the track reference to call it directly if needed.
118+
- The Track.OnDecrypted event callable is now passed the DRM and Segment objects used to Decrypt. The segment object is
119+
only passed from HLS downloads.
120+
- The Track.OnDownloaded event callable is now called BEFORE decryption, right after downloading, not after decryption.
121+
- All generated Track ID values across the codebase has moved from md5 to crc32 values as code processors complain
122+
about its use surrounding security, and it's length is too large for our use case anyway.
123+
- HLS segments are now downloaded multi-threaded first and then processed in sequence thereafter.
124+
- HLS segments are no longer decrypted one-by-one, requiring a lot of shaka-packager processes to run and close.
125+
They now merged and decrypt in groups based on their EXT-X-KEY, before being merged per discontinuity.
126+
- The DASH and HLS downloaders now pass multiple URLs to the downloader instead of one-by-one, heavily increasing speed
127+
and reliability as connections are kept alive and re-used.
128+
- Downloaders now yield back progress information in the same convention used by `rich`'s `Progress.update()` method.
129+
DASH and HLS now pass the yielded information to their progress callable instead of passing the progress callable to
130+
the downloader.
131+
- The aria2(c) downloader now uses the aria2(c) JSON-RPC interface to query for download progress updates instead of
132+
parsing the stdout data in an extremely hacky way.
133+
- The aria2(c) downloader now re-routes non-HTTP proxies via `pproxy` by a subprocess instead of the now-removed
134+
`start_pproxy` utility. This way has proven to be easier, more reliable, and prevents pproxy from messing with rich's
135+
terminal output in strange ways.
136+
- All downloader function's have an altered signature but ultimately similar. `uri` to `urls`, `out` (path) was removed,
137+
we now calculate the save path by passing an `output_dir` and `filename`. The `silent`, `segmented`, and `progress`
138+
parameters were completely removed.
139+
- All downloader `urls` can now be a string or a dictionary containing extra URL-specific options to use like
140+
URL-specific headers. It can also be a list of the two types of URLs to downloading multi-threaded.
141+
- All downloader `filenames` can be a static string, or a filename string template with a few variables to use. The
142+
template system used is f-string, e.g., `"file_{i:03}{ext}"` (ext starts with `.` if there's an extension).
143+
- DASH now updates the progress bar when merging segments.
144+
- The `Widevine.decrypt()` method now also searches for shaka-packager as just `packager` as it is the default build
145+
name. (#74)
146+
147+
### Removed
148+
149+
- The `devine auth` command and sub-commands due to lack of support, risk of data, and general quirks with it.
150+
- Removed `profiles` config, you must now specify which profile you wish to use each time with `-p/--profile`. If you
151+
use a specific profile a lot more than others, you should make it the default.
152+
- The `saldl` downloader has been removed as their binary distribution is whack and development has seemed to stall.
153+
It was only used as an alternative to what was at the time the only downloader, aria2(c), as it did not support any
154+
form of Byte Range, but `saldl` did, which was crucial for resuming extremely large downloads or complex playlists.
155+
However, now we have the requests downloader which does support the Range header.
156+
- The `Track.needs_proxy` property was removed for a few design architectural reasons.
157+
1) Design-wise it isn't valid to have --proxy (or via config/otherwise) set a proxy, then unpredictably have it
158+
bypassed or disabled. If I specify `--proxy 127.0.0.1:8080`, I would expect it to use that proxy for all
159+
communication indefinitely, not switch in and out depending on the track or service.
160+
2) With reason 1, it's also a security problem. The only reason I implemented it in the first place was so I could
161+
download faster on my home connection. This means I would authenticate and call APIs under a proxy, then suddenly
162+
download manifests and segments e.t.c under my home connection. A competent service could see that as an indicator
163+
of bad play and flag you.
164+
3) Maintaining this setup across the codebase is extremely annoying, especially because of how proxies are setup/used
165+
by Requests in the Session. There's no way to tell a request session to temporarily disable the proxy and turn it
166+
back on later, without having to get the proxy from the session (in an annoying way) store it, then remove it,
167+
make the calls, then assuming your still in the same function you can add it back. If you're not in the same
168+
function, well, time for some spaghetti code.
169+
- The `Range.Transfer.SDR_BT_601_625 = 5` key and value has been removed as I cannot find any official source to verify
170+
it as the correct use. However, usually a `transfer` value of `5` would be PAL SD material so it better matches `6`,
171+
which is (now named) `Range.Transfer.BT_601 = 6`. If you have something specifying transfer=5, just remap it to 6.
172+
- The warning log `There's no ... Audio Tracks, likely part of an invariant playlist, continuing...` message has been
173+
removed. So long as your playlist is expecting no audio tracks, or the audio is part of the video transport, then
174+
this wouldn't be a problem whatsoever. Therefore, having it log this annoying warning all the time is pointless.
175+
- The `--min-split-size` argument to the aria2(c) downloader as it was only used to disable splitting on
176+
segmented downloads, but the newer downloader system wouldn't really need or want this to be done. If aria2 has
177+
decided based on its other settings to have split a segment file, then it likely would benefit from doing so.
178+
- The `--remote-time` argument from the aria2(c) downloader as it may need to do a GET and a HEAD request to
179+
get the remote time information, slowing the download down. We don't need this information anyway as it will likely
180+
be repacked with `ffmpeg` or multiplexed with `mkvmerge`, discarding/losing that information.
181+
- DASH and HLS's 5-attempt retry loop as the downloaders will retry for us.
182+
- The `start_pproxy` utility has been removed as all uses of it now call `pproxy` via subprocess instead.
183+
- The `LANGUAGE_MUX_MAP` constant and it's usage has been removed as it is no longer necessary as of MKVToolNix v54.
184+
185+
### Fixed
186+
187+
- Uses of `__ALL__` with Class objects have been correct to `__all__` with string objects, following PEP8.
188+
- Fixed value of URL passed to `Track.get_key_id()` as it was a tuple rather than the URL string.
189+
- The `--skip-dl` flag now works again after breaking in v[1.3.0].
190+
- Move WVD file to correct location on new installations in the `wvd add` command.
191+
- Cookie data is now passed to downloaders and use URLs based on the URI it will be used for, just like a browser.
192+
- Failure to get FPS in DASH when SegmentBase isn't used.
193+
- An error message is now returned if a WVD file fails to load instead of raising an exception.
194+
- Track language information within M3U playlists are now validated with langcodes before use. Some manifests use the
195+
property for arbitrary data that their apps/players use for their own purposes.
196+
- Attempt to fix non-UTF-8 and mixed-encoding Subtitle downloads by automatically converting to UTF-8. (#43)
197+
Decoding is attempted in the following order: UTF-8, CP-1252, then finally chardet detection. If it's neither UTF-8
198+
nor CP-1252 and chardet could not detect the encoding, then it is left as-is. Conversion is done per-segment if the
199+
Subtitle is segmented, unless it's the fVTT or fTTML formats which are binary.
200+
- Chapter Character Encoding is now explicitly set to UTF-8 when muxing to an MKV container as Windows seems to default
201+
to latin1 or something, breaking Chapter names with any sort of special character within.
202+
- Subtitle passed through SubtitleEdit now explicitly use UTF-8 character encoding as it usually defaulted to UTF-8
203+
with Byte Order Marks (aka UTF-8-SIG/UTF-8-BOM).
204+
- Subtitles passed through SubtitleEdit now use the same output format as the subtitle being processed instead of SRT.
205+
- Fixed rare infinite loop when the Server hosting the init/header data/segment file responds with a `Content-Length`
206+
header with a value of `0` or smaller.
207+
- Removed empty caption lists/languages when parsing Subtitles with `Subtitle.parse()`. This stopped conversions to SRT
208+
containing the `MULTI-LANGUAGE SRT` header when there was multiple caption lists, even though only one of them
209+
actually contained captions.
210+
- Text-based Subtitle formats now try to automatically convert to UTF-8 when run through `Subtitle.parse()`.
211+
- Text-based Subtitle formats now have `‎` and `‏` HTML entities unescaped post-download as some rendering
212+
libraries seems to not decode them for us. SubtitleEdit also has problems with `/ReverseRtlStartEnd` unless it's
213+
already decoded.
214+
- Fixed two concatenation errors surrounding DASH's BaseURL, sourceURL, and media values that start with or use `../`.
215+
- Fixed the number values in the `Newly added to x/y Vaults` log, which now states `Cached n Key(s) to x/y Vaults`.
216+
- File write handler now flushes after appending a new segment to the final save path or checkpoint file, reducing
217+
memory usage by quite a bit in some scenarios.
218+
219+
### New Contributors
220+
221+
- [Shivelight](https://github.com/Shivelight)
222+
8223
## [2.2.0] - 2023-04-23
9224

10225
### Breaking Changes
@@ -428,6 +643,7 @@ This release brings a huge change to the fundamentals of Devine's logging, UI, a
428643

429644
Initial public release under the name Devine.
430645

646+
[3.0.0]: https://github.com/devine-dl/devine/releases/tag/v3.0.0
431647
[2.2.0]: https://github.com/devine-dl/devine/releases/tag/v2.2.0
432648
[2.1.0]: https://github.com/devine-dl/devine/releases/tag/v2.1.0
433649
[2.0.1]: https://github.com/devine-dl/devine/releases/tag/v2.0.1

0 commit comments

Comments
 (0)