Skip to main content
The Audio Transcription service provides automatic speech-to-text conversion for audio files, powered by AWS services through a serverless API.

Overview

The transcription system allows you to:
  • Upload audio files - Support for MP3, WAV, M4A, and OGG formats
  • Automatic transcription - AWS-powered speech recognition
  • View results - Real-time access to transcription status and results
  • Download transcripts - Get completed transcriptions
  • History - Access previously transcribed files
The service uses AWS Lambda, S3, and Transcribe services through an API Gateway endpoint. Files are uploaded to S3, processed asynchronously, and results are stored for retrieval.

Supported Audio Formats

The system accepts the following audio file types:

MP3

MPEG audio layer 3

WAV

Waveform audio format

M4A

MPEG-4 audio

OGG

Ogg Vorbis audio
Maximum file size is 50 MB (51200 KB). Larger files must be compressed or split before upload.

Transcription Workflow

1

Access transcription interface

Navigate to the transcription section from the main menu
2

Select audio file

Choose a file from your computer (MP3, WAV, M4A, or OGG)
3

Upload file

The system:
  1. Generates a pre-signed S3 upload URL
  2. Uploads the file directly to AWS S3
  3. Initiates the transcription job
4

Monitor progress

Check the status of your transcription:
  • Processing - AWS is transcribing the audio
  • Completed - Transcription is ready
  • Failed - An error occurred
5

View results

Once complete, view or download the transcribed text

API Configuration

The system connects to an AWS API Gateway endpoint:
// AudioTranscriptionController.php:12-15
public function __construct()
{
    $this->apiBaseUrl = env('TRANSCRIPTION_API_URL', 
        'https://gvs9j8cd3a.execute-api.us-east-1.amazonaws.com/prod');
}
Set the TRANSCRIPTION_API_URL in your .env file to configure the API endpoint.

Generating Upload URLs

Before uploading, the system requests a pre-signed URL from AWS:
// AudioTranscriptionController.php:28-75
public function generateUploadUrl(Request $request)
{
    $request->validate([
        'fileName' => 'required|string',
        'contentType' => 'required|string'
    ]);
    
    $url = $this->apiBaseUrl . '/generate-upload-url';
    $data = json_encode([
        'fileName' => $request->fileName,
        'contentType' => $request->contentType
    ]);
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'Content-Length: ' . strlen($data)
    ]);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    $decodedResponse = json_decode($response, true);
    return response()->json($decodedResponse, $httpCode);
}
SSL verification is disabled for development environments. Enable verification in production by removing CURLOPT_SSL_VERIFYPEER = false.

Uploading Files

Once a pre-signed URL is obtained, upload the file directly to S3:
// AudioTranscriptionController.php:80-125
public function uploadFile(Request $request)
{
    $request->validate([
        'uploadUrl' => 'required|url',
        'file' => 'required|file|mimes:mp3,wav,m4a,ogg|max:51200'
    ]);
    
    $file = $request->file('file');
    $uploadUrl = $request->uploadUrl;
    $filePath = $file->getRealPath();
    
    $ch = curl_init($uploadUrl);
    curl_setopt($ch, CURLOPT_PUT, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_INFILE, fopen($filePath, 'r'));
    curl_setopt($ch, CURLOPT_INFILESIZE, filesize($filePath));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: ' . $file->getMimeType()
    ]);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    if ($httpCode >= 200 && $httpCode < 300) {
        return response()->json([
            'success' => true, 
            'message' => 'Archivo subido exitosamente'
        ]);
    } else {
        throw new \Exception("Error al subir el archivo. Código HTTP: $httpCode");
    }
}
The upload uses HTTP PUT directly to the S3 pre-signed URL, ensuring secure and efficient file transfer.

Checking Transcription Results

Query the transcription status and results:

Get All Results

// AudioTranscriptionController.php:130-166
public function getResults(Request $request)
{
    $query = $request->get('getAll') ? ['getAll' => 'true'] : [];
    $url = $this->apiBaseUrl . '/results?' . http_build_query($query);
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    $decodedResponse = json_decode($response, true);
    return response()->json($decodedResponse, $httpCode);
}

Get Specific File Results

Search for transcription results by filename:
// AudioTranscriptionController.php:171-213
public function getResultsByFileName(Request $request)
{
    $request->validate([
        'fileName' => 'required|string'
    ]);
    
    $url = $this->apiBaseUrl . '/results?' . http_build_query([
        'fileName' => $request->fileName
    ]);
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    $decodedResponse = json_decode($response, true);
    return response()->json($decodedResponse, $httpCode);
}

Viewing Transcription History

Access the complete history of transcribed files:
// AudioTranscriptionController.php:219-267
public function getHistorial(Request $request)
{
    $url = $this->apiBaseUrl . '/results?' . http_build_query([
        'getAll' => 'true'
    ]);
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json'
    ]);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    
    $decodedResponse = json_decode($response, true);
    
    $historial = json_decode($response, true);
    
    // Sort by filename
    if (is_array($historial)) {
        usort($historial, function ($a, $b) {
            $nombreA = $a['nombre_archivo'] ?? $a['archivo'] ?? $a['filename'] ?? '';
            $nombreB = $b['nombre_archivo'] ?? $b['archivo'] ?? $b['filename'] ?? '';
            return strcasecmp($nombreB, $nombreA);
        });
    }
    
    return response()->json($historial);
}
The history includes:
  • File names
  • Upload timestamps
  • Transcription status
  • Completed transcriptions
  • Error messages (if any)

Routes

The transcription system uses these routes:
RouteMethodPurpose
/transcriptionGETShow transcription interface
/generate-upload-urlPOSTGet S3 pre-signed URL
/upload-filePOSTUpload file to S3
/get-resultsGETGet all transcription results
/get-results-by-filenameGETGet results for specific file
/get-historialGETGet complete transcription history
All routes require authentication via the auth middleware.

Error Handling

The system handles various error scenarios:

cURL Errors

if ($error) {
    throw new \Exception("cURL Error: " . $error);
}

Invalid JSON Responses

$decodedResponse = json_decode($response, true);
if (!$decodedResponse) {
    throw new \Exception("Invalid JSON response: " . $response);
}

HTTP Errors

if ($httpCode >= 200 && $httpCode < 300) {
    return response()->json(['success' => true]);
} else {
    throw new \Exception("Error al subir el archivo. Código HTTP: $httpCode");
}
All errors are logged using Laravel’s logging system:
Log::error('Error obteniendo resultados: ' . $e->getMessage());
return response()->json([
    'error' => 'Error interno del servidor: ' . $e->getMessage()
], 500);

Frontend Integration

The transcription interface uses AJAX to communicate with the backend:
  1. Select file - User chooses audio file
  2. Request URL - Call /generate-upload-url with filename and content type
  3. Upload file - POST file to pre-signed URL via /upload-file
  4. Poll results - Periodically call /get-results-by-filename to check status
  5. Display transcript - Show completed transcription when ready

AWS Architecture

The backend uses a serverless architecture:

API Gateway

REST API endpoint for requests

Lambda Functions

Serverless processing logic

S3 Bucket

Audio file storage

AWS Transcribe

Speech-to-text engine

DynamoDB

Results storage

Best Practices

  1. File preparation - Convert audio to supported formats before upload
  2. File size - Compress large files to stay under 50 MB limit
  3. Audio quality - Better audio quality produces better transcriptions
  4. Check status - Poll periodically but not too frequently (every 5-10 seconds)
  5. Handle errors - Implement retry logic for failed uploads
  6. Timeout handling - Set appropriate timeout values for large files
  7. Progress feedback - Show upload and processing progress to users
  8. Result caching - Cache transcription results to avoid repeated API calls

Troubleshooting

Upload Fails

  • Verify file format is supported
  • Check file size is under 50 MB
  • Ensure internet connection is stable
  • Verify API endpoint is accessible

Transcription Never Completes

  • Check AWS service status
  • Verify audio file is not corrupted
  • Ensure audio contains speech
  • Review CloudWatch logs for Lambda errors

Empty Results

  • Confirm file was successfully uploaded to S3
  • Check transcription job started correctly
  • Verify audio format is compatible with AWS Transcribe
  • Review error logs in the transcription results

Security Considerations

The transcription service:
  • Uses pre-signed URLs with limited validity
  • Requires authentication for all operations
  • Uploads files directly to S3 (not through application server)
  • Stores results in AWS with access controls
Enable SSL verification in production by removing or setting CURLOPT_SSL_VERIFYPEER = true in all cURL requests.

File Management

Manage uploaded audio files

AWS Integration

Other AWS-powered features

Build docs developers (and LLMs) love