Wobuzz/wobuzz/player/track.py

100 lines
2.7 KiB
Python

#!/usr/bin/python3
from pydub import AudioSegment
from pydub.effects import normalize
from pygame.mixer import Sound
from tinytag import TinyTag
SUPPORTED_FORMATS = [
"mp3",
"wav",
"ogg"
]
class Track:
"""
Class containing data for a track like file path, raw data...
"""
def __init__(self, app, path: str, property_string: str=None, cache: bool=False):
self.app = app
self.path = path
self.property_string = property_string
self.tags = TinyTag.get(self.path, ignore_errors=False, duration=False)
self.cached = False
self.audio = None
self.sound = None
self.duration = 0
self.items = []
self.occurrences = {} # all occurrences in playlists categorized by playlist and track widget
if cache:
self.cache()
def set_occurrences(self):
# set track item for every occurrence of track in a playlist
new_occurrences = {}
for item in self.items:
playlist_occurrences = new_occurrences.get(item.playlist, {})
playlist_occurrences[id(item)] = item.index
new_occurrences[item.playlist] = playlist_occurrences
self.correct_occurrences(new_occurrences)
self.occurrences = new_occurrences
def correct_occurrences(self, new_occurrences):
"""
If this track is the currently playing track, and it gets moved, this corrects the current playlist index.
"""
if self.app.player.current_playlist.current_track is self:
for item in self.items:
if (
item.playlist in self.occurrences and
self.occurrences[item.playlist][id(item)] == self.app.player.current_playlist.current_track_index
):
self.app.player.current_playlist.set_track(new_occurrences[item.playlist][id(item)])
def cache(self):
self.load_audio()
# audio = normalize(audio)
wav = self.audio.export(format="wav")
self.sound = Sound(wav)
self.duration = len(self.audio) # track duration in milliseconds
self.cached = True
def clear_cache(self):
self.cached = False
self.audio = None
self.sound = None
self.duration = 0
def load_audio(self):
file_type = self.path.split(".")[-1]
if file_type in SUPPORTED_FORMATS:
self.audio = AudioSegment.from_file(self.path)
def remaining(self, position: int):
remaining_audio = self.audio[position:]
wav = remaining_audio.export(format="wav")
sound = Sound(wav)
# return the remaining part of the track's audio and the duration of the remaining part
return sound, len(remaining_audio)