endpoint: /api/trim
- Define new api endpoint /api/trim, params: file_uuid, overwrites exisiting file on server with trimmed audio. - Remove print messages in freqsplit/postprocessing/audio_writer.export_audio() - Add new file api/utils.py for commonly used functions
This commit is contained in:
@@ -2,6 +2,7 @@ from celery import shared_task
|
|||||||
from freqsplit.input.file_reader import read_audio
|
from freqsplit.input.file_reader import read_audio
|
||||||
from freqsplit.preprocessing.classify import classify_audio
|
from freqsplit.preprocessing.classify import classify_audio
|
||||||
from freqsplit.preprocessing.normalize import normalize_audio
|
from freqsplit.preprocessing.normalize import normalize_audio
|
||||||
|
from freqsplit.preprocessing.trim import trim_audio
|
||||||
from freqsplit.postprocessing.audio_writer import export_audio
|
from freqsplit.postprocessing.audio_writer import export_audio
|
||||||
|
|
||||||
@shared_task
|
@shared_task
|
||||||
@@ -29,3 +30,13 @@ def normalize_audio_task(file_path):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@shared_task
|
||||||
|
def trim_audio_task(file_path):
|
||||||
|
"""Celery task to trim audio synchronously"""
|
||||||
|
try:
|
||||||
|
audio, sr = read_audio(file_path)
|
||||||
|
trimmed_audio = trim_audio(audio, sr)
|
||||||
|
export_audio(trimmed_audio, file_path, sr)
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
return False
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# api/utils.py
|
||||||
|
import os
|
||||||
|
|
||||||
|
def get_audio_file_path(file_uuid, base_dir):
|
||||||
|
"""Returns the full path to the audio file inside the given UUID folder."""
|
||||||
|
dir_path = os.path.join(base_dir, file_uuid)
|
||||||
|
if not os.path.exists(dir_path) or not os.listdir(dir_path):
|
||||||
|
return False
|
||||||
|
return os.path.join(dir_path, os.listdir(dir_path)[0]) # Assumes only one file exists
|
||||||
+28
-12
@@ -3,8 +3,10 @@ import uuid
|
|||||||
from rest_framework.decorators import api_view
|
from rest_framework.decorators import api_view
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
from .utils import get_audio_file_path
|
||||||
from .tasks import save_and_classify
|
from .tasks import save_and_classify
|
||||||
from .tasks import normalize_audio_task
|
from .tasks import normalize_audio_task
|
||||||
|
from .tasks import trim_audio_task
|
||||||
from freqsplit.input.format_checker import is_supported_format
|
from freqsplit.input.format_checker import is_supported_format
|
||||||
|
|
||||||
UPLOAD_DIR = "/tmp/freqsplit"
|
UPLOAD_DIR = "/tmp/freqsplit"
|
||||||
@@ -12,6 +14,8 @@ UPLOAD_DIR = "/tmp/freqsplit"
|
|||||||
# Ensure the temp directory exists
|
# Ensure the temp directory exists
|
||||||
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
#
|
||||||
|
|
||||||
# Endpoint to upload audio and classify it to audio_class
|
# Endpoint to upload audio and classify it to audio_class
|
||||||
@api_view(['POST'])
|
@api_view(['POST'])
|
||||||
def upload_audio(request):
|
def upload_audio(request):
|
||||||
@@ -57,18 +61,9 @@ def normalize_audio(request):
|
|||||||
if not file_uuid:
|
if not file_uuid:
|
||||||
return Response({"error": "Missing file_uuid"}, status=status.HTTP_400_BAD_REQUEST)
|
return Response({"error": "Missing file_uuid"}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
audio_dir = os.path.join(UPLOAD_DIR, file_uuid)
|
file_path = get_audio_file_path(file_uuid, UPLOAD_DIR)
|
||||||
|
if file_path == False:
|
||||||
if not os.path.exists(audio_dir) or not os.path.isdir(audio_dir):
|
return Response({"error": "No files found"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
return Response({"error": "File directory not found"}, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
# Get the actual file name (since there's only one file)
|
|
||||||
files = os.listdir(audio_dir)
|
|
||||||
if not files:
|
|
||||||
return Response({"error": "No file found in directory"}, status=status.HTTP_400_BAD_REQUEST)
|
|
||||||
|
|
||||||
file_name = files[0]
|
|
||||||
file_path = os.path.join(audio_dir, file_name)
|
|
||||||
|
|
||||||
# Call Celery task synchronously
|
# Call Celery task synchronously
|
||||||
task = normalize_audio_task.apply(args=(file_path,))
|
task = normalize_audio_task.apply(args=(file_path,))
|
||||||
@@ -77,3 +72,24 @@ def normalize_audio(request):
|
|||||||
return Response({"message": "Audio normalized successfully"}, status=status.HTTP_200_OK)
|
return Response({"message": "Audio normalized successfully"}, status=status.HTTP_200_OK)
|
||||||
else:
|
else:
|
||||||
return Response({"error": "Failed to normalize audio"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
return Response({"error": "Failed to normalize audio"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|
||||||
|
# Endpoint to trim audio
|
||||||
|
@api_view(['POST'])
|
||||||
|
def trim_audio(request):
|
||||||
|
"""Handles trimming of leading and trailing silence from an audio clip"""
|
||||||
|
file_uuid = request.data.get("file_uuid")
|
||||||
|
|
||||||
|
if not file_uuid:
|
||||||
|
return Response({"error": "Missing file_uuid"}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
file_path = get_audio_file_path(file_uuid, UPLOAD_DIR)
|
||||||
|
if file_path == False:
|
||||||
|
return Response({"error": "No files found"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
|
|
||||||
|
# Call Celery task synchronously
|
||||||
|
task = trim_audio_task.apply(args=(file_path,))
|
||||||
|
|
||||||
|
if task.get():
|
||||||
|
return Response({"message": "Audio trimmed successfulyl"}, status=status.HTTP_200_OK)
|
||||||
|
else:
|
||||||
|
return Response({"error": "Failed to normalize audio"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
||||||
+3
-1
@@ -18,9 +18,11 @@ from django.contrib import admin
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
from api.views import upload_audio
|
from api.views import upload_audio
|
||||||
from api.views import normalize_audio
|
from api.views import normalize_audio
|
||||||
|
from api.views import trim_audio
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('api/upload', upload_audio, name='upload_audio'),
|
path('api/upload', upload_audio, name='upload_audio'),
|
||||||
path('api/normalize', normalize_audio, name="normalize_audio")
|
path('api/normalize', normalize_audio, name="normalize_audio"),
|
||||||
|
path('api/trim', trim_audio, name='trim_audio')
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -12,9 +12,6 @@ def export_audio(audio, output_path, sr):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
print(f"Initial audio shape: {audio.shape}, dtype: {audio.dtype}, max: {np.max(audio)}, min: {np.min(audio)}")
|
|
||||||
|
|
||||||
if audio.ndim == 2 and audio.shape[0] == 2:
|
if audio.ndim == 2 and audio.shape[0] == 2:
|
||||||
# Transpose stereo audio to match the expected shape
|
# Transpose stereo audio to match the expected shape
|
||||||
audio = audio.T # From (2, num_samples) to (num_samples, 2)
|
audio = audio.T # From (2, num_samples) to (num_samples, 2)
|
||||||
@@ -26,10 +23,6 @@ def export_audio(audio, output_path, sr):
|
|||||||
if np.max(np.abs(audio)) > 0: # Avoid divide by zero
|
if np.max(np.abs(audio)) > 0: # Avoid divide by zero
|
||||||
audio = audio / np.max(np.abs(audio))
|
audio = audio / np.max(np.abs(audio))
|
||||||
|
|
||||||
# Verify final format
|
|
||||||
print(f"Final audio shape: {audio.shape}, dtype: {audio.dtype}, max: {np.max(audio)}, min: {np.min(audio)}")
|
|
||||||
|
|
||||||
|
|
||||||
sf.write(output_path, audio, sr, format='wav')
|
sf.write(output_path, audio, sr, format='wav')
|
||||||
print(f"Audio saved to {output_path}")
|
print(f"Audio saved to {output_path}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user