Angular 2中如何通过input file获取音频文件信息并上传至服务器
Hey there! Let's break down how to solve this problem step by step using Angular 2, TypeScript, and plain JS/HTML—no third-party libraries required. I'll cover the limitations you're hitting and walk through actionable code to get all the data you need, plus upload it to your server.
First, a quick note on local file paths
Browsers enforce strict security restrictions that prevent accessing the full local file path of selected files. This is intentional to protect user privacy. You can only reliably get the filename, not the full system path. So we'll focus on the other data points you need: name, size, extension, and duration.
Core approach for audio duration
We'll use the native HTML5 Audio API to load the selected audio file (via a blob URL) and listen for the loadedmetadata event, which fires once the audio's metadata (including duration) is available.
Step 1: Update your HTML
Let's add an Angular change event handler and a button to trigger the upload:
<input type="file" name="file" id="file" accept="audio/*" (change)="onAudioFileSelected($event)" > <button (click)="uploadAudio()" [disabled]="!selectedAudio" > Upload Audio </button>
Step 2: TypeScript Component Logic
Create a component to handle file selection, metadata extraction, and upload. We'll define an interface to organize the audio file data, then implement the necessary methods:
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; // Interface to structure our audio file data interface SelectedAudio { file: File; name: string; size: number; extension: string; duration: number; // Duration in seconds (can be a float) } @Component({ selector: 'app-audio-upload', templateUrl: './audio-upload.component.html' }) export class AudioUploadComponent { selectedAudio: SelectedAudio | null = null; constructor(private http: HttpClient) {} onAudioFileSelected(event: Event): void { const inputElement = event.target as HTMLInputElement; if (!inputElement.files || inputElement.files.length === 0) return; const audioFile = inputElement.files[0]; // Extract basic file info const fileExtension = audioFile.name.split('.').pop()?.toLowerCase() || ''; const initialAudioData: Partial<SelectedAudio> = { file: audioFile, name: audioFile.name, size: audioFile.size, extension: fileExtension }; // Use HTML5 Audio API to get duration const audio = new Audio(); audio.src = URL.createObjectURL(audioFile); // Wait for metadata to load audio.onloadedmetadata = () => { initialAudioData.duration = audio.duration; this.selectedAudio = initialAudioData as SelectedAudio; // Clean up the blob URL to avoid memory leaks URL.revokeObjectURL(audio.src); }; // Handle invalid audio files audio.onerror = () => { alert('Could not load the selected file. Please choose a valid audio file.'); URL.revokeObjectURL(audio.src); }; } uploadAudio(): void { if (!this.selectedAudio) return; // Create FormData to send both file and duration to the server const formData = new FormData(); formData.append('audioFile', this.selectedAudio.file); formData.append('duration', this.selectedAudio.duration.toString()); // Replace with your server's upload endpoint this.http.post('/api/upload-audio', formData) .subscribe({ next: (response) => { console.log('Upload successful:', response); // Reset the file input and selected data this.selectedAudio = null; const inputElement = document.getElementById('file') as HTMLInputElement; inputElement.value = ''; }, error: (err) => { console.error('Upload failed:', err); alert('Upload failed. Please try again.'); } }); } // Optional: Format duration into mm:ss for display formatDuration(duration: number): string { const minutes = Math.floor(duration / 60); const seconds = Math.floor(duration % 60); return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; } }
Key Details to Note
- Memory Management: Always call
URL.revokeObjectURL(audio.src)after loading the metadata—this frees up memory used by the blob URL. - Duration Formatting: The
formatDurationhelper converts raw seconds into a human-readable mm:ss string, which you can use in your template if needed. - Server Upload: We use
FormDatato package both the audio file and its duration, which is the standard way to send file data + additional fields via HTTP.
内容的提问来源于stack exchange,提问作者Pawananjay

