File size: 7,158 Bytes
d2b9965
a543f09
 
 
 
77ecfd5
d2b9965
a543f09
77ecfd5
a543f09
 
d2b9965
 
 
a543f09
 
 
 
77ecfd5
a543f09
 
 
 
 
 
 
 
 
 
 
 
d2b9965
a543f09
 
 
 
 
 
 
d2b9965
 
 
60f492b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d2b9965
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a543f09
d2b9965
 
a543f09
d2b9965
 
 
 
 
 
 
 
 
a543f09
 
d2b9965
 
 
 
 
a543f09
 
 
 
77ecfd5
a543f09
d2b9965
a543f09
d2b9965
a543f09
77ecfd5
d2b9965
 
 
 
 
 
 
 
77ecfd5
 
 
 
 
d2b9965
77ecfd5
a543f09
77ecfd5
a543f09
d2b9965
a543f09
 
77ecfd5
d2b9965
 
 
a543f09
d2b9965
 
a543f09
d2b9965
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a543f09
 
d2b9965
 
 
 
 
 
77ecfd5
a543f09
 
 
 
d2b9965
 
 
77ecfd5
a543f09
d2b9965
a543f09
d2b9965
77ecfd5
 
 
 
 
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215

import gradio as gr
import pydub
import tempfile
from pathlib import Path
import time
import os

def convert_mp3_to_flac(mp3_file_path, progress=gr.Progress()):
    """Convert MP3 file to 16-bit FLAC"""
    try:
        if not mp3_file_path:
            raise ValueError("No file uploaded")
        
        progress(0, desc="Starting conversion...")
        
        # Read MP3 file
        progress(0.2, desc="Loading MP3 file...")
        audio = pydub.AudioSegment.from_mp3(mp3_file_path)
        
        # Ensure it's 16-bit (PCM_16)
        progress(0.5, desc="Converting to 16-bit PCM...")
        audio = audio.set_sample_width(2)  # 2 bytes = 16 bits
        
        # Save as FLAC
        progress(0.8, desc="Saving as FLAC...")
        
        # Create temporary file for output
        with tempfile.NamedTemporaryFile(suffix='.flac', delete=False) as tmp:
            flac_path = tmp.name
        
        # Export as FLAC with 16-bit PCM
        audio.export(flac_path, format="flac", parameters=["-sample_fmt", "s16"])
        
        progress(1.0, desc="Conversion complete!")
        
        return flac_path
    
    except Exception as e:
        error_msg = f"Conversion failed: {str(e)}"
        raise gr.Error(error_msg)

def convert_mp3_to_flac(mp3_file_path, progress=gr.Progress()):
    """Convert MP3 file to 16-bit FLAC at 44.1kHz"""
    try:
        if not mp3_file_path:
            raise ValueError("No file uploaded")
        
        progress(0, desc="Starting conversion...")
        
        # Read MP3 file
        progress(0.2, desc="Loading MP3 file...")
        audio = pydub.AudioSegment.from_mp3(mp3_file_path)
        
        # 1. Ensure 16-bit depth
        progress(0.4, desc="Converting to 16-bit PCM...")
        audio = audio.set_sample_width(2)  # 2 bytes = 16 bits
        
        # 2. NEW STEP: Resample to 44.1 kHz if needed[citation:5][citation:7]
        # The sample rate is stored as `frame_rate` in pydub[citation:7]
        if audio.frame_rate != 44100:
            progress(0.6, desc=f"Resampling from {audio.frame_rate} Hz to 44.1 kHz...")
            audio = audio.set_frame_rate(44100)  # Resample to the required rate
        
        # Save as FLAC
        progress(0.8, desc="Saving as 44.1kHz FLAC...")
        
        # Create temporary file for output
        with tempfile.NamedTemporaryFile(suffix='.flac', delete=False) as tmp:
            flac_path = tmp.name
        
        # Export as FLAC with explicit parameters
        audio.export(flac_path, format="flac", parameters=["-sample_fmt", "s16", "-ar", "44100"])
        
        progress(1.0, desc="Conversion complete!")
        return flac_path
    
    except Exception as e:
        raise gr.Error(f"Conversion failed: {str(e)}")


def get_file_stats(file_path):
    """Get statistics about the uploaded file"""
    if not file_path or not os.path.exists(file_path):
        return "**File Statistics:** No file uploaded"
    
    try:
        audio = pydub.AudioSegment.from_mp3(file_path)
        file_size = os.path.getsize(file_path)
        
        stats = f"""
        **File Statistics:**
        - Duration: {len(audio) / 1000:.2f} seconds
        - Channels: {'Mono' if audio.channels == 1 else 'Stereo'}
        - Sample Rate: {audio.frame_rate:,} Hz
        - Bit Depth: 16-bit (output)
        - File Size: {file_size / 1024 / 1024:.2f} MB
        - Format: MP3 → FLAC
        """
        return stats
    except Exception as e:
        return f"**File Statistics:** Could not read file details - {str(e)}"

def cleanup_old_files():
    """Clean up temporary files older than 1 hour"""
    temp_dir = tempfile.gettempdir()
    current_time = time.time()
    
    for ext in ['.flac', '.mp3']:
        for file in Path(temp_dir).glob(f"*{ext}"):
            try:
                if file.stat().st_mtime < (current_time - 3600):
                    file.unlink()
            except:
                pass

# Create Gradio interface
with gr.Blocks(
    title="MP3 to 16-bit FLAC Converter",
    theme=gr.themes.Soft()
) as demo:
    
    gr.Markdown("# 🎵 MP3 to 16-bit FLAC Converter")
    gr.Markdown("Upload an MP3 file and convert it to 16-bit FLAC format")
    
    with gr.Row():
        with gr.Column(scale=1):
            mp3_input = gr.File(
                label="📁 Upload MP3 File",
                file_types=[".mp3"],
                type="filepath"
            )
            
            convert_btn = gr.Button(
                "🔄 Convert to FLAC",
                variant="primary",
                size="lg"
            )
            
            with gr.Accordion("⚙️ Conversion Settings", open=False):
                gr.Markdown("""
                **Default Settings:**
                - Output format: FLAC
                - Bit depth: 16-bit
                - Channels: Preserved from source
                - Sample rate: Preserved from source
                - Compression: Lossless
                """)
        
        with gr.Column(scale=1):
            flac_output = gr.File(
                label="💾 Download FLAC File",
                file_types=[".flac"]
            )
            
            stats_display = gr.Markdown(
                "**File Statistics:** Upload a file to see details"
            )
    
    # Info section
    with gr.Accordion("📚 How to Use & Info", open=False):
        gr.Markdown("""
        ## Usage Instructions
        
        1. **Upload** an MP3 file using the upload button or drag & drop
        2. **Check** the file statistics to verify your upload
        3. **Click** the "Convert to FLAC" button
        4. **Wait** for the conversion to complete (progress bar will show)
        5. **Download** your converted FLAC file
        
        ## Technical Information
        
        - **Input**: MP3 files of any bitrate (8-320 kbps)
        - **Output**: 16-bit FLAC (lossless compression)
        - **Maximum file size**: 200MB
        - **Processing time**: ~1-2 seconds per minute of audio
        
        ## Important Notes
        
        ⚠️ **Converting MP3 to FLAC does NOT improve audio quality**
        - MP3 is a lossy format - some audio data is permanently removed
        - FLAC is lossless but cannot restore what was lost in MP3 compression
        - The FLAC file will have the same perceived quality as the original MP3
        
        ## Use Cases
        
        - Preparing audio for editing software that prefers FLAC
        - Archiving music in a lossless format
        - Compatibility with devices that require FLAC
        """)
    
    # Connect components
    mp3_input.change(
        fn=get_file_stats,
        inputs=[mp3_input],
        outputs=[stats_display]
    )
    
    convert_btn.click(
        fn=convert_mp3_to_flac,
        inputs=[mp3_input],
        outputs=[flac_output]
    ).then(
        fn=lambda: "**Status:** Ready for new conversion",
        outputs=[stats_display]
    )

# Clean up old files and launch
if __name__ == "__main__":
    cleanup_old_files()
    demo.launch(
        server_name="0.0.0.0",
        server_port=7860,
        share=False
    )