mirror of
https://github.com/unshackle-dl/unshackle.git
synced 2026-03-09 16:09:01 +00:00
Compare commits
4 Commits
refactor/s
...
3.0.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf9087a1ce | ||
|
|
23cc351f77 | ||
|
|
132d3549f9 | ||
|
|
3ee554401a |
35
CHANGELOG.md
35
CHANGELOG.md
@@ -6,7 +6,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
||||
|
||||
This changelog is automatically generated using [git-cliff](https://git-cliff.org).
|
||||
|
||||
## [Unreleased]
|
||||
## [3.0.0] - 2026-02-15
|
||||
|
||||
### Features
|
||||
|
||||
@@ -21,6 +21,9 @@ This changelog is automatically generated using [git-cliff](https://git-cliff.or
|
||||
- *drm*: Add MonaLisa DRM support to core infrastructure
|
||||
- *audio*: Codec lists and split muxing
|
||||
- *proxy*: Add specific server selection for WindscribeVPN
|
||||
- *cdm*: Normalize CDM detection for local and remote implementations
|
||||
- *HLS*: Improve audio codec handling with error handling for codec extraction
|
||||
- *tracks*: Prioritize Atmos audio tracks over higher bitrate non-Atmos
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -53,11 +56,39 @@ This changelog is automatically generated using [git-cliff](https://git-cliff.or
|
||||
- *dl*: Always clean up hybrid temp hevc outputs
|
||||
- *hls*: Finalize n_m3u8dl_re outputs
|
||||
- *downloader*: Restore requests progress for single-url downloads
|
||||
- *dl*: Invert audio codec suffixing when splitting
|
||||
- *dl*: Support snake_case keys for RemoteCdm
|
||||
- *aria2c*: Warn on config mismatch and wait for RPC ready
|
||||
- *serve*: [**breaking**] Make PlayReady users config consistently a mapping
|
||||
- *dl*: Preserve proxy_query selector (not resolved URI)
|
||||
- *gluetun*: Stop leaking proxy/vpn secrets to process list
|
||||
- *monalisa*: Avoid leaking secrets and add worker safety
|
||||
- *dl*: Avoid selecting all variants when multiple audio codecs requested
|
||||
- *hls*: Keep range offset numeric and align MonaLisa licensing
|
||||
- *titles*: Remove trailing space from HDR dynamic range label
|
||||
- *config*: Normalize playready_remote remote_cdm keys
|
||||
- *titles*: Avoid None/double spaces in HDR tokens
|
||||
- *naming*: Keep technical tokens with scene_naming off
|
||||
- *api*: Log PSSH extraction failures
|
||||
- *proxies*: Harden surfshark and windscribe selection
|
||||
- *service*: Redact proxy credentials in logs
|
||||
- *monalisa*: Harden wasm calls and license handling
|
||||
- *hls*: Remove no-op encryption_data reassignment
|
||||
- *serve*: Default PlayReady access to none
|
||||
- *tracks*: Close temp session and improve path type error
|
||||
- *main*: Update copyright year dynamically in version display
|
||||
|
||||
### Reverts
|
||||
|
||||
- *monalisa*: Pass key via argv again
|
||||
|
||||
### Documentation
|
||||
|
||||
- Add configuration documentation WIP
|
||||
- *changelog*: Add 2.4.0 release notes
|
||||
- *changelog*: Update cliff config and regenerate changelog
|
||||
- *changelog*: Complete 2.4.0 notes
|
||||
- *config*: Clarify sdh_method uses subtitle-filter
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
@@ -451,7 +482,7 @@ This changelog is automatically generated using [git-cliff](https://git-cliff.or
|
||||
- Reorganize Planned Features section in README for clarity
|
||||
- Improve track selection logic in dl.py
|
||||
|
||||
[unreleased]: https://github.com/unshackle-dl/unshackle/compare/2.3.0..HEAD
|
||||
[3.0.0]: https://github.com/unshackle-dl/unshackle/compare/2.3.0..3.0.0
|
||||
[2.3.0]: https://github.com/unshackle-dl/unshackle/compare/2.2.0..2.3.0
|
||||
[2.2.0]: https://github.com/unshackle-dl/unshackle/compare/2.1.0..2.2.0
|
||||
[2.1.0]: https://github.com/unshackle-dl/unshackle/compare/2.0.0..2.1.0
|
||||
|
||||
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "unshackle"
|
||||
version = "2.4.0"
|
||||
version = "3.0.0"
|
||||
description = "Modular Movie, TV, and Music Archival Software."
|
||||
authors = [{ name = "unshackle team" }]
|
||||
requires-python = ">=3.10,<3.13"
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "2.4.0"
|
||||
__version__ = "3.0.0"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import atexit
|
||||
import logging
|
||||
from datetime import datetime
|
||||
|
||||
import click
|
||||
import urllib3
|
||||
@@ -58,7 +59,7 @@ def main(version: bool, debug: bool) -> None:
|
||||
r" ▀▀▀ ▀▀ █▪ ▀▀▀▀ ▀▀▀ · ▀ ▀ ·▀▀▀ ·▀ ▀.▀▀▀ ▀▀▀ ",
|
||||
style="ascii.art",
|
||||
),
|
||||
f"v [repr.number]{__version__}[/] - © 2025 - github.com/unshackle-dl/unshackle",
|
||||
f"v [repr.number]{__version__}[/] - © 2025-{datetime.now().year} - github.com/unshackle-dl/unshackle",
|
||||
),
|
||||
(1, 11, 1, 10),
|
||||
expand=True,
|
||||
|
||||
@@ -116,9 +116,14 @@ class HLS:
|
||||
|
||||
for playlist in self.manifest.playlists:
|
||||
audio_group = playlist.stream_info.audio
|
||||
if audio_group:
|
||||
audio_codec = Audio.Codec.from_codecs(playlist.stream_info.codecs)
|
||||
audio_codecs_by_group_id[audio_group] = audio_codec
|
||||
audio_codec: Optional[Audio.Codec] = None
|
||||
if audio_group and playlist.stream_info.codecs:
|
||||
try:
|
||||
audio_codec = Audio.Codec.from_codecs(playlist.stream_info.codecs)
|
||||
except ValueError:
|
||||
audio_codec = None
|
||||
if audio_codec:
|
||||
audio_codecs_by_group_id[audio_group] = audio_codec
|
||||
|
||||
try:
|
||||
# TODO: Any better way to figure out the primary track type?
|
||||
|
||||
@@ -221,13 +221,15 @@ class Tracks:
|
||||
self.videos.sort(key=lambda x: not is_close_match(language, [x.language]))
|
||||
|
||||
def sort_audio(self, by_language: Optional[Sequence[Union[str, Language]]] = None) -> None:
|
||||
"""Sort audio tracks by bitrate, descriptive, and optionally language."""
|
||||
"""Sort audio tracks by bitrate, Atmos, descriptive, and optionally language."""
|
||||
if not self.audio:
|
||||
return
|
||||
# descriptive
|
||||
self.audio.sort(key=lambda x: x.descriptive)
|
||||
# bitrate (within each descriptive group)
|
||||
# bitrate (highest first)
|
||||
self.audio.sort(key=lambda x: float(x.bitrate or 0.0), reverse=True)
|
||||
# Atmos tracks first (prioritize over higher bitrate non-Atmos)
|
||||
self.audio.sort(key=lambda x: not x.atmos)
|
||||
# descriptive tracks last
|
||||
self.audio.sort(key=lambda x: x.descriptive)
|
||||
# language
|
||||
for language in reversed(by_language or []):
|
||||
if str(language) in ("all", "best"):
|
||||
|
||||
Reference in New Issue
Block a user