File size: 3,690 Bytes
5244c19
0ebc3c4
3b6cf03
98acae8
89b6dcb
 
 
98acae8
c6b75bd
fb39589
98acae8
c6b75bd
a355cb0
 
 
98acae8
5244c19
89b6dcb
fb39589
89b6dcb
 
 
 
 
c6b75bd
89b6dcb
 
 
 
 
 
 
 
 
 
c6b75bd
89b6dcb
 
 
 
 
c6b75bd
 
 
89b6dcb
c6b75bd
89b6dcb
c6b75bd
 
 
89b6dcb
 
fb39589
 
 
 
 
c6b75bd
fb39589
 
 
89b6dcb
 
 
e691691
3b6cf03
89b6dcb
 
 
3b6cf03
 
 
 
c6b75bd
98acae8
 
3b6cf03
fb39589
 
 
 
 
3b6cf03
 
580dcd1
 
3b6cf03
fb39589
580dcd1
fb39589
3b6cf03
98acae8
c6b75bd
98acae8
 
 
 
 
 
89b6dcb
 
 
 
 
 
 
98acae8
89b6dcb
 
fa08cd8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import gradio as gr
import os
from moviepy.editor import AudioFileClip, ImageClip
from pathlib import Path
import subprocess
import uuid
import shutil


output_dir = Path("temp/").absolute()
output_dir.mkdir(exist_ok=True, parents=True)

os.chdir(
    output_dir
)  # change working directory to output_dir because the hf spaces model has no option to specify output directory ¯\_(ツ)_/¯


class SpotifyApi:
    spotify_directory = Path("spotify")
    final_directory = output_dir

    def __init__(self):
        self.setup_spotipy

    def setup_spotipy(self) -> None:
        # Check if the credentials file exists
        if not os.path.exists("spotif.rc"):
            with open("spotify.rc", "w") as f:
                f.write(
                    f"{os.environ['SPOTIFY_USERNAME']} {os.environ['SPOTIFY_PASSWORD']}"
                )
            subprocess.call(["spodcast", "-l", "spotify.rc"])
        else:
            pass

    def download_episode(self, episode_url) -> str:
        # Generate a 8 character random string
        foldername = str(uuid.uuid4())[:8]
        out_path = (self.spotify_directory / foldername).resolve()
        subprocess.call(["spodcast", "--root-path", out_path, episode_url])
        self.foldername = foldername
        mp3_path = self.get_final_mp3()
        assert mp3_path is not None
        return mp3_path

    def get_final_mp3(self) -> str | None:
        # Look in all the subdirectories of spotify for the mp3 file
        for root, dirs, files in os.walk(
            Path(self.spotify_directory / self.foldername)
        ):
            for file in files:
                if file.endswith(".mp3"):
                    final_mp3 = (
                        Path(self.final_directory / self.foldername)
                        .with_suffix(".mp3")
                        .absolute()
                    )
                    shutil.copy(os.path.join(root, file), final_mp3)
                    shutil.rmtree(
                        Path(self.spotify_directory / self.foldername).absolute()
                    )
                    return final_mp3.as_posix()


def process_inputs(prompt, audio, spotify_url) -> str:
    image = get_stable_diffusion_image(prompt)
    if spotify_url:
        spotify = SpotifyApi()
        audio = spotify.download_episode(spotify_url)
    video = add_static_image_to_audio(image, audio)
    return video


def add_static_image_to_audio(image, audio) -> str:
    """Create and save a video file to `output_path` after
    combining a static image that is located in `image_path`
    with an audio file in `audio_path`"""
    # Generate a random folder name and change directories to there
    foldername = str(uuid.uuid4())[:8]
    vid_output_dir = Path(output_dir / foldername)
    vid_output_dir.mkdir(exist_ok=True, parents=True)
    os.chdir(vid_output_dir)
    audio_clip = AudioFileClip(audio)
    image_clip = ImageClip(image)
    video_clip = image_clip.set_audio(audio_clip)
    video_clip.duration = audio_clip.duration
    video_clip.fps = 1
    path = Path("output.mp4").as_posix()
    video_clip.write_videofile(path)
    return path


def get_stable_diffusion_image(prompt) -> str:
    stable_diffusion = gr.Blocks.load(name="spaces/stabilityai/stable-diffusion")
    gallery_dir = stable_diffusion(prompt, fn_index=2)
    return [os.path.join(gallery_dir, img) for img in os.listdir(gallery_dir)][0]


iface = gr.Interface(
    fn=process_inputs,
    inputs=[
        gr.Textbox(label="Describe your podcast clip"),
        gr.Audio(type="filepath", label="Upload an mp3"),
        gr.Textbox(label="Or Paste a spotify episode link"),
    ],
    outputs="video",
)


iface.launch()