Update app.py
Browse files
app.py
CHANGED
|
@@ -6,12 +6,13 @@ from scipy.fftpack import fft
|
|
| 6 |
import streamlit as st
|
| 7 |
import tempfile
|
| 8 |
import os
|
|
|
|
| 9 |
|
| 10 |
# Streamlit App
|
| 11 |
def main():
|
| 12 |
-
st.title("MP3 Fourier Transform Visualizer")
|
| 13 |
|
| 14 |
-
uploaded_file = st.file_uploader("
|
| 15 |
|
| 16 |
if uploaded_file is not None:
|
| 17 |
# Convert MP3 to WAV for easier processing
|
|
@@ -45,17 +46,20 @@ def main():
|
|
| 45 |
|
| 46 |
fft_frames = np.array(fft_frames)
|
| 47 |
|
| 48 |
-
# Create animation
|
| 49 |
-
fig, ax = plt.subplots()
|
| 50 |
-
line, = ax.plot(freqs, fft_frames[0])
|
| 51 |
ax.set_xlim(0, np.max(freqs))
|
| 52 |
ax.set_ylim(0, np.max(fft_frames))
|
| 53 |
-
ax.set_xlabel("Frequency (Hz)")
|
| 54 |
-
ax.set_ylabel("Amplitude")
|
| 55 |
-
ax.set_title("
|
|
|
|
|
|
|
| 56 |
|
| 57 |
def update(frame):
|
| 58 |
line.set_ydata(fft_frames[frame])
|
|
|
|
| 59 |
return line,
|
| 60 |
|
| 61 |
ani = FuncAnimation(fig, update, frames=len(fft_frames), blit=True)
|
|
@@ -65,11 +69,23 @@ def main():
|
|
| 65 |
ani.save(temp_video.name, fps=30, extra_args=['-vcodec', 'libx264'])
|
| 66 |
video_path = temp_video.name
|
| 67 |
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
# Cleanup temporary files
|
| 71 |
os.remove(temp_mp3.name)
|
| 72 |
os.remove(video_path)
|
|
|
|
|
|
|
| 73 |
|
| 74 |
if __name__ == "__main__":
|
| 75 |
main()
|
|
|
|
| 6 |
import streamlit as st
|
| 7 |
import tempfile
|
| 8 |
import os
|
| 9 |
+
import subprocess
|
| 10 |
|
| 11 |
# Streamlit App
|
| 12 |
def main():
|
| 13 |
+
st.title("MP3 Fourier Transform Visualizer: 科学未来館エディション")
|
| 14 |
|
| 15 |
+
uploaded_file = st.file_uploader("音声ファイルをアップロード (MP3)", type=["mp3"])
|
| 16 |
|
| 17 |
if uploaded_file is not None:
|
| 18 |
# Convert MP3 to WAV for easier processing
|
|
|
|
| 46 |
|
| 47 |
fft_frames = np.array(fft_frames)
|
| 48 |
|
| 49 |
+
# Create animation with colorful design
|
| 50 |
+
fig, ax = plt.subplots(facecolor="black")
|
| 51 |
+
line, = ax.plot(freqs, fft_frames[0], lw=2, color="cyan")
|
| 52 |
ax.set_xlim(0, np.max(freqs))
|
| 53 |
ax.set_ylim(0, np.max(fft_frames))
|
| 54 |
+
ax.set_xlabel("Frequency (Hz)", color="white")
|
| 55 |
+
ax.set_ylabel("Amplitude", color="white")
|
| 56 |
+
ax.set_title("音の周波数スペクトル", color="white")
|
| 57 |
+
ax.tick_params(colors="white")
|
| 58 |
+
fig.patch.set_facecolor("black")
|
| 59 |
|
| 60 |
def update(frame):
|
| 61 |
line.set_ydata(fft_frames[frame])
|
| 62 |
+
line.set_color(plt.cm.jet(frame / len(fft_frames))) # Dynamic color
|
| 63 |
return line,
|
| 64 |
|
| 65 |
ani = FuncAnimation(fig, update, frames=len(fft_frames), blit=True)
|
|
|
|
| 69 |
ani.save(temp_video.name, fps=30, extra_args=['-vcodec', 'libx264'])
|
| 70 |
video_path = temp_video.name
|
| 71 |
|
| 72 |
+
# Merge audio and video using ffmpeg
|
| 73 |
+
output_path = tempfile.NamedTemporaryFile(delete=False, suffix="_output.mp4").name
|
| 74 |
+
audio_path = tempfile.NamedTemporaryFile(delete=False, suffix=".wav").name
|
| 75 |
+
audio.export(audio_path, format="wav")
|
| 76 |
+
|
| 77 |
+
ffmpeg_command = [
|
| 78 |
+
"ffmpeg", "-y", "-i", video_path, "-i", audio_path, "-c:v", "copy", "-c:a", "aac", output_path
|
| 79 |
+
]
|
| 80 |
+
subprocess.run(ffmpeg_command)
|
| 81 |
+
|
| 82 |
+
st.video(output_path)
|
| 83 |
|
| 84 |
# Cleanup temporary files
|
| 85 |
os.remove(temp_mp3.name)
|
| 86 |
os.remove(video_path)
|
| 87 |
+
os.remove(audio_path)
|
| 88 |
+
os.remove(output_path)
|
| 89 |
|
| 90 |
if __name__ == "__main__":
|
| 91 |
main()
|