feat: codec alternative

pull/1/head
WorldObservationLog 5 months ago
parent ec29ef8580
commit ee7c8de4d4
  1. 6
      config.toml
  2. 2
      src/config.py
  3. 14
      src/mp4.py
  4. 4
      src/rip.py

@ -9,9 +9,11 @@ agentPort = 10020
suMethod = "su -c" suMethod = "su -c"
[download] [download]
atmosConventToM4a = false codecAlternative = true
codecPriority = ["alac", "ec3", "ac3", "aac"]
atmosConventToM4a = true
songNameFormat = "{disk}-{tracknum:02d} {title}" songNameFormat = "{disk}-{tracknum:02d} {title}"
dirPathFormat = "downloads/{artist}/{album}" dirPathFormat = "downloads/{album_artist}/{album}"
saveLyrics = true saveLyrics = true
saveCover = true saveCover = true
coverFormat = "jpg" coverFormat = "jpg"

@ -16,6 +16,8 @@ class Device(BaseModel):
class Download(BaseModel): class Download(BaseModel):
codecAlternative: bool
codecPriority: list[str]
atmosConventToM4a: bool atmosConventToM4a: bool
songNameFormat: str songNameFormat: str
dirPathFormat: str dirPathFormat: str

@ -8,6 +8,7 @@ from typing import Tuple
import m3u8 import m3u8
import regex import regex
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from loguru import logger
from src.exceptions import CodecNotFoundException from src.exceptions import CodecNotFoundException
from src.metadata import SongMetadata from src.metadata import SongMetadata
@ -22,12 +23,21 @@ async def get_available_codecs(m3u8_url: str) -> Tuple[list[str], list[str]]:
return codecs, codec_ids return codecs, codec_ids
async def extract_media(m3u8_url: str, codec: str) -> Tuple[str, list[str], str]: async def extract_media(m3u8_url: str, codec: str, song_metadata: SongMetadata,
codec_priority: list[str], alternative_codec: bool = False ) -> Tuple[str, list[str]]:
parsed_m3u8 = m3u8.load(m3u8_url) parsed_m3u8 = m3u8.load(m3u8_url)
specifyPlaylist = find_best_codec(parsed_m3u8, codec) specifyPlaylist = find_best_codec(parsed_m3u8, codec)
if not specifyPlaylist and alternative_codec:
logger.warning(f"Codec {codec} of song: {song_metadata.artist} - {song_metadata.title} did not found")
for a_codec in codec_priority:
specifyPlaylist = find_best_codec(parsed_m3u8, a_codec)
if specifyPlaylist:
codec = a_codec
break
if not specifyPlaylist: if not specifyPlaylist:
raise CodecNotFoundException raise CodecNotFoundException
selected_codec = specifyPlaylist.media[0].group_id selected_codec = specifyPlaylist.media[0].group_id
logger.info(f"Selected codec: {selected_codec} for song: {song_metadata.artist} - {song_metadata.title}")
stream = m3u8.load(specifyPlaylist.absolute_uri) stream = m3u8.load(specifyPlaylist.absolute_uri)
skds = [key.uri for key in stream.keys if regex.match('(skd?://[^"]*)', key.uri)] skds = [key.uri for key in stream.keys if regex.match('(skd?://[^"]*)', key.uri)]
keys = [prefetchKey] keys = [prefetchKey]
@ -46,7 +56,7 @@ async def extract_media(m3u8_url: str, codec: str) -> Tuple[str, list[str], str]
for key in skds: for key in skds:
if key.endswith(key_suffix) or key.endswith(CodecKeySuffix.KeySuffixDefault): if key.endswith(key_suffix) or key.endswith(CodecKeySuffix.KeySuffixDefault):
keys.append(key) keys.append(key)
return stream.segment_map[0].absolute_uri, keys, selected_codec return stream.segment_map[0].absolute_uri, keys
def extract_song(raw_song: bytes, codec: str) -> SongInfo: def extract_song(raw_song: bytes, codec: str) -> SongInfo:

@ -29,8 +29,8 @@ async def rip_song(song: Song, auth_params: GlobalAuthParams, codec: str, config
lyrics = await get_song_lyrics(song.id, song.storefront, auth_params.accountAccessToken, lyrics = await get_song_lyrics(song.id, song.storefront, auth_params.accountAccessToken,
auth_params.dsid, auth_params.accountToken) auth_params.dsid, auth_params.accountToken)
song_metadata.lyrics = lyrics song_metadata.lyrics = lyrics
song_uri, keys, selected_codec = await extract_media(song_data.attributes.extendedAssetUrls.enhancedHls, codec) song_uri, keys = await extract_media(song_data.attributes.extendedAssetUrls.enhancedHls, codec, song_metadata,
logger.info(f"Selected codec: {selected_codec} for song: {song_metadata.artist} - {song_metadata.title}") config.download.codecPriority, config.download.codecAlternative)
logger.info(f"Downloading song: {song_metadata.artist} - {song_metadata.title}") logger.info(f"Downloading song: {song_metadata.artist} - {song_metadata.title}")
raw_song = await download_song(song_uri) raw_song = await download_song(song_uri)
song_info = extract_song(raw_song, codec) song_info = extract_song(raw_song, codec)

Loading…
Cancel
Save