File size: 2,542 Bytes
160e8ff
f8b6c9f
 
 
 
 
 
 
160e8ff
 
f8b6c9f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# app.py

import streamlit as st
from pydub import AudioSegment
from io import BytesIO
import tempfile
from datetime import timedelta

# ✅ ffmpeg はサーバにインストール済みなので、明示的なパス指定は不要!
# AudioSegment.converter や AudioSegment.ffprobe は書かなくてOK

# アプリ設定
st.set_page_config(page_title="音声カッター", layout="centered")
st.title("✂️ 音声ファイルカッター(シンプル&見やすい)")

uploaded_file = st.file_uploader("音声ファイルを選んでください(mp3, wav, m4a)", type=["mp3", "wav", "m4a"])

def format_time(seconds: float) -> str:
    return str(timedelta(seconds=round(seconds)))

if uploaded_file:
    st.audio(uploaded_file)

    try:
        # 一時ファイルに保存
        with tempfile.NamedTemporaryFile(delete=False, suffix=".tmp") as tmp:
            tmp.write(uploaded_file.read())
            audio = AudioSegment.from_file(tmp.name)

        duration_sec = len(audio) / 1000.0

        if duration_sec < 0.01:
            st.warning("❗ 音声が短すぎて切り出せません。")
            st.stop()

        st.subheader("🎚️ 切り出したい範囲を選んでください")
        start_sec, end_sec = st.slider(
            f"範囲(全長 {format_time(duration_sec)})",
            min_value=0.0,
            max_value=duration_sec,
            value=(0.0, min(1.0, duration_sec)),
            step=0.01
        )

        col1, col2 = st.columns(2)
        col1.write(f"▶️ 開始時間: `{format_time(start_sec)}`")
        col2.write(f"⏹️ 終了時間: `{format_time(end_sec)}`")

        if st.button("🎬 切り出して保存"):
            if start_sec >= end_sec:
                st.warning("⚠️ 終了時間は開始時間より後にしてください。")
            else:
                start_ms = int(start_sec * 1000)
                end_ms = int(end_sec * 1000)
                cut_audio = audio[start_ms:end_ms]

                buf = BytesIO()
                cut_audio.export(buf, format="mp3")
                buf.seek(0)

                st.success("✅ 切り出し完了!")
                st.audio(buf, format="audio/mp3")
                st.download_button(
                    label="💾 ダウンロード(MP3)",
                    data=buf,
                    file_name="cut_audio.mp3",
                    mime="audio/mpeg"
                )

    except Exception as e:
        st.error(f"❌ エラーが発生しました:\n\n{e}")