在 iOS 中使用 AVPlayer 播放音視頻時,若需程式化控制音量(如添加音量滑桿),不能直接設置 player.volume(該屬性已棄用/無效),需使用 AVMutableAudioMix 配合 AVMutableAudioMixInputParameters 實現。
- (void)setPlayerVolume:(float)volume {
// 1. 獲取當前播放項的資源
AVPlayerItem *playerItem = self.player.currentItem;
AVAsset *asset = playerItem.asset;
// 2. 獲取所有音頻軌道
NSArray *audioTracks = [asset tracksWithMediaType:AVMediaTypeAudio];
if (audioTracks.count == 0) return; // 無音軌
// 3. 為每個音軌創建輸入參數
NSMutableArray *audioParams = [NSMutableArray array];
for (AVAssetTrack *track in audioTracks) {
AVMutableAudioMixInputParameters *inputParams =
[AVMutableAudioMixInputParameters audioMixInputParameters];
// 關鍵:設置音量(0.0 - 1.0)及生效時間
[inputParams setVolume:volume atTime:kCMTimeZero];
// 關鍵:關聯具體音軌 ID
[inputParams setTrackID:[track trackID]];
[audioParams addObject:inputParams];
}
// 4. 創建音頻混合
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
[audioMix setInputParameters:audioParams];
// 5. 應用到播放項
[playerItem setAudioMix:audioMix];
}
- (IBAction)volumeSliderChanged:(UISlider *)sender {
[self setPlayerVolume:sender.value];
}
AVMutableAudioMixInputParameters 必須關聯具體音軌 trackID,否則混合無效atTime:kCMTimeZero 表示立即生效,可設置漸變:[inputParams setVolumeRampFromStartVolume:1.0 toEndVolume:0.0 timeRange:timeRange]// 錯誤示範 1:未設置 trackID
AVMutableAudioMixInputParameters *params = [AVMutableAudioMixInputParameters audioMixInputParameters];
[params setVolume:0.5 atTime:kCMTimeZero];
// 缺少 [params setTrackID:track.trackID] - 無效!
// 錯誤示範 2:嘗試直接設置 player.volume
self.player.volume = 0.5; // 無效,AVPlayer 無此屬性(或已棄用)
// 錯誤示範 3:使用 AVAudioPlayer 混淆
// AVAudioPlayer 有 volume 屬性,但 AVPlayer 沒有
@interface AudioVolumeController : NSObject
@property (nonatomic, weak) AVPlayer *player;
- (void)setVolume:(float)volume;
- (float)currentVolume; // 需額外記錄,AVPlayer 無直接獲取
@end
@implementation AudioVolumeController
- (void)setVolume:(float)volume {
AVPlayerItem *item = self.player.currentItem;
if (!item) return;
AVAsset *asset = item.asset;
NSArray *tracks = [asset tracksWithMediaType:AVMediaTypeAudio];
if (tracks.count == 0) return;
NSMutableArray *paramsArray = [NSMutableArray array];
for (AVAssetTrack *track in tracks) {
AVMutableAudioMixInputParameters *params = [AVMutableAudioMixInputParameters audioMixInputParameters];
[params setVolume:volume atTime:kCMTimeZero];
[params setTrackID:[track trackID]];
[paramsArray addObject:params];
}
AVMutableAudioMix *mix = [AVMutableAudioMix audioMix];
[mix setInputParameters:paramsArray];
[item setAudioMix:mix];
_currentVolume = volume; // 記錄當前音量
}
@end
CMTimeRange timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(1.0, 600)); // 1秒
[inputParams setVolumeRampFromStartVolume:currentVolume toEndVolume:targetVolume timeRange:timeRange];