首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

iOS AVPlayer 使用 AVMutableAudioMix 實現精確音量控制

     編輯:程式設計綜合問答

在 iOS 中使用 AVPlayer 播放音視頻時,若需程式化控制音量(如添加音量滑桿),不能直接設置 player.volume(該屬性已棄用/無效),需使用 AVMutableAudioMix 配合 AVMutableAudioMixInputParameters 實現。

正確實現方案

1. 獲取音軌並創建輸入參數

- (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];
}

2. 滑桿綁定調用

- (IBAction)volumeSliderChanged:(UISlider *)sender {
    [self setPlayerVolume:sender.value];
}

關鍵點解析

  • trackID 必須設置:每個 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];
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved