Skip to content
This repository has been archived by the owner on Jan 12, 2025. It is now read-only.

Commit

Permalink
fix: incomplete audio
Browse files Browse the repository at this point in the history
  • Loading branch information
WorldObservationLog committed Jun 13, 2024
1 parent 2ff9dce commit 954cb3c
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ class RetryableDecryptException(Exception):
...

class FailedGetM3U8FromDeviceException(Exception):
...

class SongNotPassIntegrityCheckException(Exception):
...
11 changes: 11 additions & 0 deletions src/mp4.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,14 @@ async def fix_esds_box(raw_song: bytes, song: bytes) -> bytes:
final_song = f.read()
tmp_dir.cleanup()
return final_song


async def check_song_integrity(song: bytes) -> bool:
tmp_dir = TemporaryDirectory()
name = uuid.uuid4().hex
song_name = Path(tmp_dir.name) / Path(f"{name}.m4a")
with open(song_name.absolute(), "wb") as f:
f.write(song)
output = subprocess.run(f"ffmpeg -y -v error -i {song_name.absolute()} -c:a pcm_s16le -f null /dev/null", capture_output=True)
tmp_dir.cleanup()
return not bool(output.stderr)
9 changes: 8 additions & 1 deletion src/rip.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
import subprocess

from loguru import logger
from tenacity import retry, retry_if_exception_type, stop_after_attempt

from src.api import (get_song_info, get_song_lyrics, get_album_info, download_song,
get_m3u8_from_api, get_artist_info, get_songs_from_artist, get_albums_from_artist,
get_playlist_info_and_tracks, exist_on_storefront_by_album_id, exist_on_storefront_by_song_id)
from src.config import Config
from src.adb import Device
from src.decrypt import decrypt
from src.exceptions import SongNotPassIntegrityCheckException
from src.metadata import SongMetadata
from src.models import PlaylistInfo
from src.mp4 import extract_media, extract_song, encapsulate, write_metadata, fix_encapsulate, fix_esds_box
from src.mp4 import extract_media, extract_song, encapsulate, write_metadata, fix_encapsulate, fix_esds_box, \
check_song_integrity
from src.save import save
from src.types import GlobalAuthParams, Codec
from src.url import Song, Album, URLType, Artist, Playlist
Expand All @@ -23,6 +26,7 @@

@logger.catch
@timeit
@retry(retry=retry_if_exception_type(SongNotPassIntegrityCheckException), stop=stop_after_attempt(1))
async def rip_song(song: Song, auth_params: GlobalAuthParams, codec: str, config: Config, device: Device,
force_save: bool = False, specified_m3u8: str = "", playlist: PlaylistInfo = None):
async with task_lock:
Expand Down Expand Up @@ -109,6 +113,9 @@ async def rip_song(song: Song, auth_params: GlobalAuthParams, codec: str, config
song = await fix_encapsulate(song)
if codec == Codec.AAC or codec == Codec.AAC_DOWNMIX or codec == Codec.AAC_BINAURAL:
song = await fix_esds_box(song_info.raw, song)
if not await check_song_integrity(song):
logger.warning(f"Song {song_metadata.artist} - {song_metadata.title} did not pass the integrity check!")
raise SongNotPassIntegrityCheckException
filename = await save(song, codec, song_metadata, config.download, playlist)
logger.info(f"Song {song_metadata.artist} - {song_metadata.title} saved!")
if config.download.afterDownloaded:
Expand Down

0 comments on commit 954cb3c

Please sign in to comment.