Spaces:
No application file
No application file
from __future__ import annotations | |
from typing import List, Dict | |
from moviepy.editor import concatenate_audioclips, AudioClip, AudioFileClip | |
from ...data import MediaMap, MediaMapEmb, MetaInfo, MediaMapSeq | |
from ...data.clip.clip_process import find_time_by_stage | |
from ...data.emb.h5py_emb import H5pyMediaMapEmb | |
from ...utils.util import load_dct_from_file | |
from .clip_process import get_stageseq_from_clipseq | |
from .music_clip import MusicClip, MusicClipSeq | |
from .meta_info import MusicMetaInfo | |
class MusicMap(MediaMap): | |
def __init__( | |
self, | |
meta_info: MetaInfo, | |
clipseq: MusicClipSeq, | |
lyricseq: MusicClipSeq = None, | |
stageseq: MusicClipSeq = None, | |
frameseq: MusicClipSeq = None, | |
emb: MediaMapEmb = None, | |
**kwargs, | |
): | |
self.lyricseq = lyricseq | |
super().__init__(meta_info, clipseq, stageseq, frameseq, emb, **kwargs) | |
if self.stageseq is None: | |
self.stageseq = MusicClipSeq.from_data( | |
get_stageseq_from_clipseq(self.clipseq) | |
) | |
self.stageseq.preprocess() | |
def preprocess(self): | |
if ( | |
hasattr(self.meta_info, "target_stages") | |
and self.meta_info.target_stages is not None | |
): | |
self.set_start_end_by_target_stages() | |
super().preprocess() | |
self.spread_metainfo_2_clip( | |
target_keys=[ | |
"media_path", | |
"media_map_path", | |
"emb_path", | |
"media_duration", | |
"mediaid", | |
"media_name", | |
"emb", | |
] | |
) | |
def set_start_end_by_target_stages(self): | |
target_stages = self.meta_info.target_stages | |
if not isinstance(target_stages, List): | |
target_stages = [target_stages] | |
start, _ = find_time_by_stage(self.stageseq, target_stages[0]) | |
_, end = find_time_by_stage(self.stageseq, target_stages[-1]) | |
self.meta_info.start = start | |
self.meta_info.end = end | |
def audio_clip(self) -> AudioFileClip: | |
"""读取实际ClipSeq中的音频 | |
Returns: | |
AudioClip: Moviepy中的audio_clip | |
""" | |
audio_clip = AudioFileClip(self.meta_info.media_path) | |
audio_clip = audio_clip.subclip(self.meta_info.start, self.meta_info.end) | |
return audio_clip | |
def from_json_path( | |
cls, path: Dict, emb_path: str, media_path: str = None, **kwargs | |
) -> MusicMap: | |
media_map = load_dct_from_file(path) | |
emb = H5pyMediaMapEmb(emb_path) | |
return cls.from_data(media_map, emb=emb, media_path=media_path, **kwargs) | |
def from_data( | |
cls, data: Dict, emb: H5pyMediaMapEmb, media_path: str = None, **kwargs | |
) -> MusicMap: | |
meta_info = MusicMetaInfo.from_data(data.get("meta_info", {})) | |
meta_info.media_path = media_path | |
clipseq = MusicClipSeq.from_data(data.get("clipseq", [])) | |
stageseq = MusicClipSeq.from_data(data.get("stageseq", [])) | |
lyricseq = MusicClipSeq.from_data(data.get("lyricseq", [])) | |
target_keys = ["meta_info", "clipseq", "frameseq", "stageseq", "lyricseq"] | |
dct = {k: data[k] for k in data.keys() if k not in target_keys} | |
dct.update(**kwargs) | |
video_map = MusicMap( | |
meta_info=meta_info, | |
clipseq=clipseq, | |
stageseq=stageseq, | |
lyricseq=lyricseq, | |
emb=emb, | |
**dct, | |
) | |
return video_map | |
def to_dct( | |
self, target_keys: List[str] = None, ignored_keys: List[str] = None | |
) -> Dict: | |
dct = {} | |
dct["meta_info"] = self.meta_info.to_dct( | |
target_keys=target_keys, ignored_keys=ignored_keys | |
) | |
dct["clipseq"] = self.clipseq.to_dct( | |
target_keys=target_keys, ignored_keys=ignored_keys | |
) | |
if self.frameseq is not None: | |
dct["frameseq"] = self.frameseq.to_dct( | |
target_keys=target_keys, ignored_keys=ignored_keys | |
) | |
else: | |
dct["frameseq"] = None | |
if self.stageseq is not None: | |
dct["stageseq"] = self.stageseq.to_dct( | |
target_keys=target_keys, ignored_keys=ignored_keys | |
) | |
else: | |
dct["stageseq"] = None | |
dct["lyricseq"] = self.lyricseq.to_dct( | |
target_keys=target_keys, ignored_keys=ignored_keys | |
) | |
return dct | |
class MusicMapSeq(MediaMapSeq): | |
def __init__(self, maps: List[MusicMap]) -> None: | |
super().__init__(maps) | |
def audio_clip(self) -> AudioFileClip: | |
audio_clip_lst = [m.audi_clip for m in self.maps] | |
audio_clip = concatenate_audioclips(audio_clip_lst) | |
return audio_clip | |