AudioEditor / tabs /audio_merger_tab.py
Ahmet Emre Şafak
fix
f056450
# tabs/audio_merger_tab.py - Audio Merger Tab Component
import gradio as gr
from numpy import ndarray
from utils.audio_utils import load_audio_info, format_time, merge_audio_files
def update_file_status(audio1_file, audio2_file):
"""Update the status when audio files are uploaded"""
if not audio1_file and not audio2_file:
return "No files uploaded yet", "πŸ”„ Ready to upload audio files"
total_duration = 0
valid_files = 0
file_info = []
# Check first audio file
if audio1_file:
try:
audio_data, sample_rate, duration = load_audio_info(audio1_file)
if audio_data is not None:
valid_files += 1
total_duration += duration
file_info.append(f" 1. First Audio: {duration:.1f}s ({sample_rate:,} Hz)")
else:
file_info.append(f" 1. First Audio: ❌ Invalid file")
except:
file_info.append(f" 1. First Audio: ❌ Error loading file")
# Check second audio file
if audio2_file:
try:
audio_data, sample_rate, duration = load_audio_info(audio2_file)
if audio_data is not None:
valid_files += 1
total_duration += duration
file_info.append(f" 2. Second Audio: {duration:.1f}s ({sample_rate:,} Hz)")
else:
file_info.append(f" 2. Second Audio: ❌ Invalid file")
except:
file_info.append(f" 2. Second Audio: ❌ Error loading file")
if valid_files == 0:
status = "❌ No valid audio files found"
details = "Please upload valid audio files (MP3, WAV, FLAC, etc.)"
elif valid_files == 1:
status = f"πŸ“ 1 valid file uploaded ({format_time(total_duration)})"
details = "Upload one more file to enable merging\n" + "\n".join(file_info)
else:
status = f"πŸ“ 2 files ready ({format_time(total_duration)} total)"
details = f"Files ready for merging:\n" + "\n".join(file_info)
return status, details
def process_merge(audio1_file, audio2_file) -> tuple[tuple[int, ndarray] | None, str]:
"""Process merging of two audio files"""
if not audio1_file or not audio2_file:
return None, "❌ Please upload both audio files to merge"
# Create file paths list for the merge function
file_paths = [audio1_file, audio2_file]
# Call the merge function
result, status = merge_audio_files(file_paths)
return result, status
def reset_everything():
"""Reset all components to initial state"""
return None, None, None, "No files uploaded yet", "πŸ”„ Ready to upload audio files", "Ready to merge! Upload both audio files to get started."
def create_audio_merger_tab():
"""Create the audio merger tab interface"""
gr.Markdown("Upload two audio files and merge them in sequence. The first audio will play before the second audio.")
with gr.Row():
with gr.Column(scale=2):
# Audio Upload Section
gr.Markdown("### πŸ“ Upload Audio Files")
with gr.Row():
audio1_file = gr.Audio(
label="🎡 First Audio File",
type="filepath",
interactive=True
)
audio2_file = gr.Audio(
label="🎡 Second Audio File",
type="filepath",
interactive=True
)
# File status
file_status = gr.Textbox(
value="No files uploaded yet",
label="πŸ“Š Upload Status",
interactive=False,
lines=1
)
# Detailed file info
file_details = gr.Textbox(
value="πŸ”„ Ready to upload audio files",
label="πŸ“‹ File Details",
interactive=False,
lines=4
)
with gr.Column(scale=1):
gr.Markdown("### πŸŽ›οΈ Merge Controls")
merge_btn = gr.Button(
"🎡 Merge Audio Files",
variant="primary",
size="lg"
)
clear_btn = gr.Button(
"πŸ—‘οΈ Clear All Files",
variant="secondary",
size="lg"
)
# Instructions
gr.Markdown("""
**πŸ“‹ Instructions:**
1. **Upload** first audio file (will play first)
2. **Upload** second audio file (will play second)
3. **Merge** files in sequence
4. **Download** the merged result
**🎯 Features:**
β€’ Automatic sample rate conversion
β€’ Stereo to mono conversion
β€’ Duration calculations
β€’ High-quality WAV output
""")
# Results section
with gr.Row():
with gr.Column(scale=1):
# Status output
merge_status = gr.Textbox(
value="Ready to merge! Upload both audio files to get started.",
label="πŸ” Merge Status & Details",
interactive=False,
lines=8
)
with gr.Column(scale=1):
# Audio output
merged_audio = gr.Audio(
label="🎡 Merged Audio Result",
type="numpy",
interactive=False
)
# Event handlers
audio1_file.change(
fn=update_file_status,
inputs=[audio1_file, audio2_file],
outputs=[file_status, file_details]
)
audio2_file.change(
fn=update_file_status,
inputs=[audio1_file, audio2_file],
outputs=[file_status, file_details]
)
merge_btn.click(
fn=process_merge,
inputs=[audio1_file, audio2_file],
outputs=[merged_audio, merge_status]
)
clear_btn.click(
fn=reset_everything,
outputs=[audio1_file, audio2_file, merged_audio, file_status, file_details, merge_status]
)