susnato commited on
Commit
e9a98af
1 Parent(s): 4691428

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -0
app.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import shutil
4
+ import librosa
5
+ import binascii
6
+ import warnings
7
+ import midi2audio
8
+ import pytube as pt # to download the youtube videos as audios
9
+ import gradio as gr
10
+ from transformers import Pop2PianoForConditionalGeneration, Pop2PianoProcessor
11
+
12
+
13
+ yt_video_dir = "./yt_dir"
14
+ outputs_dir = "./midi_wav_outputs"
15
+ os.makedirs(outputs_dir, exist_ok=True)
16
+ os.makedirs(yt_video_dir, exist_ok=True)
17
+
18
+ device = "cuda" if torch.cuda.is_available() else "cpu"
19
+ model = Pop2PianoForConditionalGeneration.from_pretrained("sweetcocoa/pop2piano").to(device)
20
+ processor = Pop2PianoProcessor.from_pretrained("sweetcocoa/pop2piano")
21
+ composers = model.generation_config.composer_to_feature_token.keys()
22
+
23
+ def get_audio_from_yt_video(yt_link):
24
+ try:
25
+ yt = pt.YouTube(yt_link)
26
+ t = yt.streams.filter(only_audio=True)
27
+ filename = os.path.join(yt_video_dir, binascii.hexlify(os.urandom(8)).decode() + ".mp4")
28
+ t[0].download(filename=filename)
29
+ except:
30
+ warnings.warn(f"Video Not Found at {yt_link}")
31
+ filename = None
32
+
33
+ return filename, filename
34
+
35
+ def prepare_output_file(tokenizer_output):
36
+ # Add some random values so that no two file names are same
37
+ output_file_name = "output_" + binascii.hexlify(os.urandom(8)).decode()
38
+ midi_output = os.path.join(outputs_dir, output_file_name + ".mid")
39
+
40
+ # write the .mid file
41
+ tokenizer_output[0].write(midi_output)
42
+
43
+ # convert .mid file to .wav using `midi2audio`
44
+ wav_output = midi_output.replace(".mid", ".wav")
45
+ midi2audio.FluidSynth().midi_to_audio(midi_output, wav_output)
46
+
47
+ from IPython.display import Audio
48
+ return wav_output, wav_output, midi_output
49
+
50
+ def inference(file_uploaded, composer):
51
+ # to save the native sampling rate of the file, sr=None is used, but this can cause some silent errors where the
52
+ # generated output will not be upto the desired quality. If that happens please consider switching sr to 44100 Hz.
53
+ waveform, sr = librosa.load(file_uploaded, sr=None)
54
+
55
+ inputs = processor(audio=waveform, sampling_rate=sr, return_tensors="pt").to(device)
56
+ model_output = model.generate(input_features=inputs["input_features"], composer=composer)
57
+ tokenizer_output = processor.batch_decode(token_ids=model_output.to("cpu"), feature_extractor_output=inputs.to("cpu"))["pretty_midi_objects"]
58
+
59
+ return prepare_output_file(tokenizer_output)
60
+
61
+
62
+ block = gr.Blocks()
63
+
64
+
65
+ with block:
66
+ gr.HTML(
67
+ """
68
+ <div style="text-align: center; max-width: 700px; margin: 0 auto;">
69
+ <div
70
+ style="
71
+ display: inline-flex;
72
+ align-items: center;
73
+ gap: 0.8rem;
74
+ font-size: 1.75rem;
75
+ "
76
+ >
77
+ <h1 style="font-weight: 900; margin-bottom: 7px;">
78
+ Pop2piano
79
+ </h1>
80
+ </div>
81
+ <p style="margin-bottom: 10px; font-size: 94%">
82
+ A demo for Pop2Piano:Pop Audio-based Piano Cover Generation.<br>
83
+ Please select the composer(Arranger) and upload the pop audio or enter the YouTube link and then click Generate.
84
+ </p>
85
+ </div>
86
+ """
87
+ )
88
+ with gr.Group():
89
+ with gr.Box():
90
+ with gr.Row().style(mobile_collapse=False, equal_height=True):
91
+ file_uploaded = gr.Audio(label="Upload an audio", type="filepath")
92
+
93
+ with gr.Column():
94
+ with gr.Row():
95
+ yt_link = gr.Textbox(label="Enter YouTube link of the Video")
96
+ yt_btn = gr.Button("Get Audio from the YT link(Press this before pressing Generate)")
97
+
98
+
99
+ yt_audio_path = gr.Audio(label="Audio Extracted from the YouTube Video", interactive=False)
100
+
101
+ yt_btn.click(get_audio_from_yt_video, inputs=[yt_link], outputs=[yt_audio_path, file_uploaded])
102
+
103
+ with gr.Box():
104
+ with gr.Row().style(mobile_collapse=False, equal_height=True):
105
+ composer = gr.Dropdown(label="Arranger", choices=composers, value="composer1")
106
+
107
+ with gr.Row().style(mobile_collapse=False, equal_height=True):
108
+ btn = gr.Button("Generate")
109
+
110
+ with gr.Box():
111
+ with gr.Row().style(mobile_collapse=False, equal_height=True):
112
+ wav_output2 = gr.File(label="Download the Generated MIDI (.wav)")
113
+ wav_output1 = gr.Audio(label="Listen to the Generated MIDI")
114
+ midi_output = gr.File(label="Download the Generated MIDI (.mid)")
115
+ btn.click(inference, inputs=[file_uploaded, composer], outputs=[wav_output1, wav_output2, midi_output])
116
+
117
+ gr.Examples([
118
+ ["./examples/custom_song.mp3", "composer1"],
119
+ ["./examples/BornThisWay.mp3", "composer1"],
120
+ ["./examples/Sk8erBoi.mp3", "composer2"],
121
+ ],
122
+ fn=inference,
123
+ inputs=[file_uploaded, composer],
124
+ outputs=[wav_output1, wav_output2, midi_output],
125
+ cache_examples=True
126
+ )
127
+ gr.HTML(
128
+ """
129
+ <div class="footer">
130
+ <p><a href="http://sweetcocoa.github.io/pop2piano_samples" style="text-decoration: underline;" target="_blank">Project Page</a>
131
+ </p>
132
+ </div>
133
+ """
134
+ )
135
+
136
+ block.launch(debug=False)
137
+ shutil.rmtree("./midi_wav_outputs")