You need to enable JavaScript to run this app.
导航
Master M3U8 播放源的多清晰度和多音轨管理
最近更新时间:2025.10.09 15:34:30首次发布时间:2025.09.29 19:58:22
复制全文
我的收藏
有用
有用
无用
无用

对于标准的 Master M3U8 播放源,播放器 SDK 提供了精细的控制能力,允许开发者在播放生命周期的不同阶段介入,精确选择要使用的视频流(清晰度)和音频流(音轨)。

起播时选择清晰度与音轨

通过设置 masterPlaylistDelegate,您可以在播放器 SDK 解析完 M3U8 文件后、开始下载媒体数据前,通过代理方法返回您期望的视频流和音轨的索引,从而控制起播。具体工作流程如下:

  1. 设置代理:为播放器实例设置 masterPlaylistDelegate 并遵循 TTVideoEngineMasterPlaylistDelegate 协议。

  2. 接收流信息:当 M3U8 解析完成后,SDK 触发 onMasterPlaylist 回调。您可以在此获取并保存包含所有视频流 variantStreams 和音频流 renditionsmasterPlaylist 对象。

    // 遵循 TTVideoEngineMasterPlaylistDelegate 协议
    // @interface YourViewController () <TTVideoEngineMasterPlaylistDelegate>
    
    // 设置代理
    self.videoEngine.masterPlaylistDelegate = self;
    
    #pragma mark - TTVideoEngineMasterPlaylistDelegate
    /**
     * M3U8 解析完成的回调。
     * 在此处保存 masterPlaylist 对象,以便在播放中切换清晰度或音轨时使用。
     */
    - (void)videoEngine:(TTVideoEngine *)videoEngine onMasterPlaylist:(TTVideoEngineMasterPlaylist *)masterPlaylist {
        self.masterPlaylist = masterPlaylist; 
        NSLog(@"M3U8 解析完成,可用视频流为:%ld", (long)masterPlaylist.variantStreams.count);
    }
    
  3. 返回决策索引:通过 indexOfVariantOnPlayMasterPlaylistindexOfRenditionOnPlayMasterPlaylist 返回您选定的视频流和音频流的索引。以下示例代码展示了以 720p 分辨率和英文音轨起播:

    // 返回起播的视频流的序号,-1 表示自动选择
    - (int)videoEngine:(TTVideoEngine *)videoEngine indexOfVariantOnPlayMasterPlaylist:(TTVideoEngineMasterPlaylist *)masterPlaylist {
        if (self.masterPlaylistPlayTargetIndex >= -1 && self.masterPlaylistPlayTargetIndex < (int)masterPlaylist.variantStreams.count) {
            return self.masterPlaylistPlayTargetIndex;
        }
        NSLog(@"清晰度选择错误:当前视频支持: -1 ~ %d,将播放默认清晰度", (int)(masterPlaylist.variantStreams.count - 1));
        return -1;
    }
    
    // 返回起播的音频流的 streamId,-1 表示自动选择
    - (int)videoEngine:(TTVideoEngine *)videoEngine indexOfRenditionOnPlayMasterPlaylist:(TTVideoEngineMasterPlaylist *)masterPlaylist {
        if (self.masterPlaylistAudioTrackIndex == -1) {
            return -1;
        }
        
        if (self.masterPlaylistAudioTrackIndex >= 0 && self.masterPlaylistAudioTrackIndex < (int)masterPlaylist.renditions.count) {
            return [[self.masterPlaylist.renditions objectAtIndex:self.masterPlaylistAudioTrackIndex].inStreamId intValue];;
        }
        NSLog(@"清晰度选择错误(rendition):当前视频支持: -1 ~ %d,将播放默认 rendition", (int)(masterPlaylist.renditions.count - 1));
        return -1;
    }
    

播放中切换清晰度与音轨

切换视频流(按 Bandwidth)

要切换视频清晰度,您需要获取目标流的带宽值,并调用 setIntOption 方法,将 PLAYER_OPTION_SET_MASTER_M3U8_VIDEO_BANDWIDTH 作为键,带宽值作为值传入。

NSString* inputBitrate = [_inputBitrateTextView.text stringByTrim];
// 通过 setOptionForKey 切换视频流
[self.player.videoEngine setOptionForKey:VEKKeySetMasterm3u8VideoBandwidth_NSInteger value:@(inputBitrate.intValue)];

切换音频流(按 Info ID)

要切换音轨,您需要获取目标音轨的 InfoId,并调用 setOptionForKey:value: 方法,将 VEKKeyPlayerSwitchAudioInfoId_NSInteger 作为键,InfoId 作为值传入。

NSString* inputStreamId = [_inputStreamIdTextView.text stringByTrim];
// 通过 setOptionForKey 切换音频流
[self.player.videoEngine setOptionForKey:VEKKeyPlayerSwitchAudioInfoId_NSInteger value:@(inputStreamId.intValue)];

预加载时选择清晰度与音轨

如果您使用 SDK 提供的预加载策略,同样可以介入并指定预加载哪些流。通过设置 TTVideoEnginePreloadDelegate,您可以在预加载任务解析完 M3U8 后,通过代理方法返回要预加载的流的索引。

// 设置预加载代理
// @interface YourAppDelegate () <TTVideoEnginePreloadDelegate>
[TTVideoEngine ls_setPreloadDelegate:self];

#pragma mark - TTVideoEnginePreloadDelegate

// 返回预加载的视频流的序号,-1 表示自动选择
- (int)indexOfVariantOnPreloadMasterPlaylist:(TTVideoEngineMasterPlaylist *)masterPlaylist {
    if (self.masterPlaylistPreloadTargetIndex >= -1 && self.masterPlaylistPreloadTargetIndex < (int)masterPlaylist.variantStreams.count) {
        return self.masterPlaylistPreloadTargetIndex;
    }
    NSLog(@"清晰度选择错误:当前视频支持: -1 ~ %d,将预加载默认清晰度", (int)(masterPlaylist.variantStreams.count - 1));
    return -1;
}

// 返回预加载的音频流的序号,-1 表示自动选择
- (int)indexOfRendtionOnPreloadMasterPlaylist:(TTVideoEngineMasterPlaylist *)masterPlaylist {
    if (masterPlaylist.renditions.count == 0) {
        return -1;
    }
    
    if (self.masterPlaylistPreloadTargetIndex >= -1 && self.masterPlaylistPreloadTargetIndex < (int)masterPlaylist.renditions.count) {
        return self.masterPlaylistPreloadTargetIndex;
    }    
  NSLog(@"清晰度选择错误(rendition):当前视频支持: -1 ~ %d,将预加载默认 rendition", (int)(masterPlaylist.renditions.count - 1));
    return -1;
}