From a00b66d55e1d6d43263fc75fc2c830d2e818268a Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 6 Feb 2022 00:23:32 +0300 Subject: [PATCH 1/3] add option to pass AuidioSegment variable as input data to recognize_song --- shazamio/api.py | 9 +++++---- shazamio/converter.py | 3 +-- shazamio/utils.py | 10 ++++++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/shazamio/api.py b/shazamio/api.py index ca2575a..236d99d 100644 --- a/shazamio/api.py +++ b/shazamio/api.py @@ -1,6 +1,7 @@ import pathlib import uuid import time +from pydub import AudioSegment from typing import Dict, Any, Union @@ -9,7 +10,7 @@ from .enums import GenreMusic from .converter import Converter, Geo from .typehints import CountryCode -from .utils import get_song_bytes +from .utils import get_song class Shazam(Converter, Geo): @@ -218,15 +219,15 @@ async def listening_counter(self, track_id: int) -> Dict[str, Any]: async def recognize_song( self, - data: Union[str, pathlib.Path, bytes, bytearray] + data: Union[str, pathlib.Path, bytes, bytearray, AudioSegment] ) -> Dict[str, Any]: """ Creating a song signature based on a file and searching for this signature in the shazam database. :param data: Path to song file or bytes :return: Dictionary with information about the found song """ - data_bytes = await get_song_bytes(data=data) - audio = self.normalize_audio_data(data_bytes) + song = await get_song(data=data) + audio = self.normalize_audio_data(song) signature_generator = self.create_signature_generator(audio) signature = signature_generator.get_next_signature() while not signature: diff --git a/shazamio/converter.py b/shazamio/converter.py index f2408c1..4fe14b1 100644 --- a/shazamio/converter.py +++ b/shazamio/converter.py @@ -46,8 +46,7 @@ def data_search(timezone: str, uri: str, samplems: int, timestamp: int) -> dict: 'timestamp': timestamp, 'context': {}, 'geolocation': {}} @staticmethod - def normalize_audio_data(song_data: bytes) -> AudioSegment: - audio = AudioSegment.from_file(BytesIO(song_data)) + def normalize_audio_data(audio: AudioSegment) -> AudioSegment: audio = audio.set_sample_width(2) audio = audio.set_frame_rate(16000) audio = audio.set_channels(1) diff --git a/shazamio/utils.py b/shazamio/utils.py index be702ce..1ff22a2 100644 --- a/shazamio/utils.py +++ b/shazamio/utils.py @@ -1,5 +1,7 @@ import pathlib from typing import Union +from pydub import AudioSegment +from io import BytesIO import aiofiles import aiohttp @@ -23,11 +25,15 @@ async def get_file_bytes(file: FileT) -> bytes: return await f.read() -async def get_song_bytes(data: SongT) -> bytes: +async def get_song(data: SongT) -> bytes: if isinstance(data, (str, pathlib.Path)): - return await get_file_bytes(file=data) + song_bytes = await get_file_bytes(file=data) + return AudioSegment.from_file(BytesIO(song_bytes)) if isinstance(data, (bytes, bytearray)): + return AudioSegment.from_file(BytesIO(data)) + + if isinstance(data, AudioSegment): return data From cc5e52691016bf894153e16a4cd2754bcab89cda Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 6 Feb 2022 01:04:08 +0300 Subject: [PATCH 2/3] fixed unused import --- shazamio/converter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/shazamio/converter.py b/shazamio/converter.py index 4fe14b1..572700f 100644 --- a/shazamio/converter.py +++ b/shazamio/converter.py @@ -1,4 +1,3 @@ -from io import BytesIO from typing import Union from pydub import AudioSegment From 99868fd30ea4b9af66730fe8d7d04dac91624599 Mon Sep 17 00:00:00 2001 From: dotX12 Date: Sat, 9 Apr 2022 21:26:40 +0300 Subject: [PATCH 3/3] Fixes for #18: Models added for TrackInfo._sections: LyricsSection ArtistSection Changed access to attributes: timeskew - > time_skew frequencyskew -> frequency_skew tabname -> tab_name toptracks -> top_tracks lyricsid -> lyrics_id providername -> provider_name commontrackid -> common_track_id beacondata -> beacon_data retryms -> retry_ms --- shazamio/factory.py | 41 ++++++++++++++++++++++++++++++++ shazamio/factory_misc.py | 14 ++++++++++- shazamio/models.py | 51 ++++++++++++++++++++++++++++++++++++---- 3 files changed, 101 insertions(+), 5 deletions(-) diff --git a/shazamio/factory.py b/shazamio/factory.py index 5e05843..ba6d0cc 100644 --- a/shazamio/factory.py +++ b/shazamio/factory.py @@ -62,6 +62,7 @@ class FactorySchemas: name_mapping={ "matches": "matches", "location": "location", + "retry_ms": "retryms", "timestamp": "timestamp", "timezone": "timezone", "track": "track", @@ -69,3 +70,43 @@ class FactorySchemas: }, skip_internal=True ) + + FACTORY_LYRICS_SECTION = Schema( + name_mapping={ + "type": "type", + "text": "text", + "footer": "footer", + "tab_name": "tabname", + "beacon_data": "beacondata", + }, + ) + + FACTORY_BEACON_DATA_LYRICS_SECTION = Schema( + name_mapping={ + "lyrics_id": "lyricsid", + "provider_name": "providername", + "common_track_id": "commontrackid", + } + ) + + FACTORY_ARTIST_SECTION = Schema( + name_mapping={ + "type": "type", + "id": "id", + "name": "name", + "verified": "verified", + "actions": "actions", + "tab_name": "tabname", + "top_tracks": "toptracks", + } + ) + + FACTORY_MATCH_MODEL = Schema( + name_mapping={ + "id": "id", + "offset": "offset", + "channel": "channel", + "time_skew": "timeskew", + "frequency_skew": "frequencyskew", + } + ) diff --git a/shazamio/factory_misc.py b/shazamio/factory_misc.py index 7c60645..5bf31e3 100644 --- a/shazamio/factory_misc.py +++ b/shazamio/factory_misc.py @@ -2,7 +2,15 @@ from shazamio.factory import FactorySchemas from shazamio.models import ArtistInfo -from shazamio.models import SongSection, VideoSection, RelatedSection +from shazamio.models import ( + SongSection, + VideoSection, + RelatedSection, + LyricsSection, + BeaconDataLyricsSection, + ArtistSection, + MatchModel, +) from shazamio.models import TrackInfo from shazamio.models import YoutubeData from shazamio.models import ResponseTrack @@ -11,6 +19,10 @@ TrackInfo: FactorySchemas.FACTORY_TRACK_SCHEMA, SongSection: FactorySchemas.FACTORY_SONG_SECTION_SCHEMA, VideoSection: FactorySchemas.FACTORY_VIDEO_SECTION_SCHEMA, + LyricsSection: FactorySchemas.FACTORY_LYRICS_SECTION, + BeaconDataLyricsSection: FactorySchemas.FACTORY_BEACON_DATA_LYRICS_SECTION, + ArtistSection: FactorySchemas.FACTORY_ARTIST_SECTION, + MatchModel: FactorySchemas.FACTORY_MATCH_MODEL, RelatedSection: FactorySchemas.FACTORY_RELATED_SECTION_SCHEMA, YoutubeData: FactorySchemas.FACTORY_YOUTUBE_TRACK_SCHEMA, ResponseTrack: FactorySchemas.FACTORY_RESPONSE_TRACK_SCHEMA, diff --git a/shazamio/models.py b/shazamio/models.py index 8cfa61e..570449b 100644 --- a/shazamio/models.py +++ b/shazamio/models.py @@ -72,6 +72,43 @@ class SongSection: metadata: List[SongMetadata] +@dataclass +class BaseIdTypeModel: + type: str + id: str + + +@dataclass +class TopTracksModel: + url: str + + +@dataclass +class ArtistSection: + type: str + id: str + name: str + verified: bool + actions: List[BaseIdTypeModel] + tab_name: str + top_tracks: TopTracksModel + + +class BeaconDataLyricsSection: + lyrics_id: str + provider_name: str + common_track_id: str + + +@dataclass +class LyricsSection: + type: str + text: List[str] + footer: str + tab_name: str + beacon_data: Optional[BeaconDataLyricsSection] + + @dataclass class VideoSection: type: str @@ -103,8 +140,8 @@ class MatchModel: id: str offset: float channel: str - timeskew: float - frequencyskew: float + time_skew: float + frequency_skew: float @dataclass @@ -143,7 +180,13 @@ class TrackInfo(Factory): spotify_url: Optional[str] = field(default=None) spotify_uri: Optional[str] = field(default=None) youtube_link: Optional[str] = None - _sections: Optional[List[Union[SongSection, VideoSection, RelatedSection]]] = field( + _sections: Optional[List[Union[ + SongSection, + VideoSection, + RelatedSection, + ArtistSection, + LyricsSection, + ]]] = field( default_factory=list ) @@ -172,7 +215,7 @@ def __youtube_link(self): @dataclass class ResponseTrack: tag_id: Optional[UUID] - retryms: Optional[int] = field(default=None) + retry_ms: Optional[int] = field(default=None) location: Optional[LocationModel] = field(default=None) matches: List[MatchModel] = field(default_factory=list) timestamp: Optional[int] = field(default=None)