【问题标题】:Subtitles for AVPlayer/MPMoviePlayerControllerAVPlayer/MPMoviePlayerController 的字幕
【发布时间】:2012-07-16 13:00:52
【问题描述】:

我正在使用 m3u8 视频格式流式传输视频,现在我需要显示相同的字幕。

我在 Apple 文档中搜索,发现可以通过使用 AVPlayerclosedCaptionDisplayEnabled 属性来实现。

我很想知道字幕的格式应该是什么? .srt 格式可以吗?

我也可以使用MPMoviePlayerController 实现同样的效果吗?

感谢任何帮助。

【问题讨论】:

  • Apple 文档在这一点上措辞准确。它只说closedCaptionDisplayEnabled“[i]表示播放器是否使用隐藏式字幕”。它没有说任何关于字幕的内容。在我的测试中(在 OS X 上),该属性对字幕没有影响;它适用于隐藏式字幕。 (您可以通过使用 EyeTV 录制隐藏式字幕电视自行测试,然后将其导出为 iPhone 和 MPEG-2 混合格式,然后使用 HandBrake 转换后者。EyeTV 到 iPhone 的导出将具有 CC 轨道;HandBrake rip会有一个字幕轨道。)

标签: mpmovieplayercontroller avfoundation avplayer subtitle transport-stream


【解决方案1】:

2020 年 3 月 6 日更新: 在 GitHub 上,jbweimar 创建了一个示例项目,该项目使用了看起来很有前途的 AVAssetResourceLoaderDelegate 方法:https://github.com/jbweimar/external-webvtt-example


2018 年 10 月 30 日更新:值得检查 this answer by an Apple engineer(感谢 @allenlini 提供 pointing it out)。他提出了一个涉及AVAssetResourceLoaderDelegate 的解决方案。我自己没有尝试过,但它可能是比我下面的更好的解决方案。


原答案:

似乎在您的 m3u8 流媒体描述中引用您的 WebVTT 文件是官方支持的方式。 “事后”添加它们似乎不受官方支持(参见this statement by an Apple engineer (bottom of the page))。

这 - 然而 - 并不意味着你不能让它工作;-)。 在 Chris Adamson、this post on the Apple Developer Forumsthis Ray Wenderlich tutorial by Abdul Azeemthis great presentationsample project (ZIP) 的帮助下,我能够让它工作。这是 Abdul Azeem 的示例代码和 Chris 的示例项目的修改版本。

注意您需要如何使用AVMediaTypeText 而不是AVMediaTypeSubtitle。这似乎是 iOS 中的一个错误。

// 1 - Load video asset
AVAsset *videoAsset = [AVURLAsset assetWithURL:[[NSBundle mainBundle] URLForResource:@"video" withExtension:@"mp4"]];

// 2 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances.
AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init];

// 3 - Video track
AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo
                                                                    preferredTrackID:kCMPersistentTrackID_Invalid];
[videoTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                    ofTrack:[[videoAsset tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0]
                     atTime:kCMTimeZero error:nil];

// 4 - Subtitle track
AVURLAsset *subtitleAsset = [AVURLAsset assetWithURL:[[NSBundle mainBundle] URLForResource:@"subtitles" withExtension:@"vtt"]];

AVMutableCompositionTrack *subtitleTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeText
                                                                       preferredTrackID:kCMPersistentTrackID_Invalid];

[subtitleTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)
                       ofTrack:[[subtitleAsset tracksWithMediaType:AVMediaTypeText] objectAtIndex:0]
                        atTime:kCMTimeZero error:nil];

// 5 - Set up player
AVPlayer *player = [AVPlayer playerWithPlayerItem: [AVPlayerItem playerItemWithAsset:mixComposition]];

【讨论】:

  • 非常感谢您的精彩帖子。您能否提及我们如何设置元数据。让 titleMetadataItem = AVMutableMetadataItem() titleMetadataItem.locale = NSLocale.current titleMetadataItem.key = AVMetadataCommonKeyTitle as (NSCopying & NSObjectProtocol)? titleMetadataItem.keySpace = AVMetadataKeySpaceCommon titleMetadataItem.value = self.assetObject.title as (NSCopying & NSObjectProtocol)?
  • @Johannes Fahrenkrug:这个解决方案是否适用于来自远程 m3u8 播放列表的真实 HLS 流?我试图在没有运气的情况下在 Swift 中做到这一点。你能看看我的帖子吗:stackoverflow.com/questions/43161124/…。谢谢!
  • 这是一篇不错的文章“将字幕从单独的 WebVTT 文件添加到 AVAsset/PlayerItem”forums.developer.apple.com/thread/45060
  • @allenlinli 哇,这是一个很棒的解决方案!谢谢分享!!
  • @m_katsifarakis 酷!是的,请发布更新!另请务必查看此链接:forums.developer.apple.com/thread/45060#202064
【解决方案2】:

这是@JohannesFahrenkrug answer 的 Swift 版本。希望这对某人有用:

    let localVideoAsset = Bundle.main.url(forResource: "L1C1P1C3", withExtension: "mp4")

    //Create AVMutableComposition
    let videoPlusSubtitles = AVMutableComposition()

    //Adds video track
    let videoTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid)

    try? videoTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, localVideoAsset.duration),
                                of: localVideoAsset.tracks(withMediaType: .video)[0],
                                at: kCMTimeZero)

    //Adds subtitle track
    let subtitleAsset = AVURLAsset(url: Bundle.main.url(forResource: "L1C1P1C3", withExtension: ".mp4.vtt")!)

    let subtitleTrack = videoPlusSubtitles.addMutableTrack(withMediaType: .text, preferredTrackID: kCMPersistentTrackID_Invalid)

    try? subtitleTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, localVideoAsset.duration),
                                        of: subtitleAsset.tracks(withMediaType: .text)[0],
                                        at: kCMTimeZero)

【讨论】:

  • 我对 URL localVideoAsset 如何具有持续时间成员感到困惑?
【解决方案3】:

AVPlayer 和 MPMoviePlayerController 都可以显示字幕。

不同之处似乎在于,使用 AVPlayer,您可以使用 closedCaptionDisplayEnabled 属性控制是否显示字幕。

使用 MPMoviePlayerController,用户可以使用设置应用中的开关控制是否显示字幕。您无法在应用程序中对此进行编程控制。

【讨论】:

  • closedCaptionDisplayEnabled 切换隐藏式字幕,而不是字幕。它们是两个不同的东西,该属性对字幕没有影响。 (一个警告:我只在 OS X 上试过这个,而不是 iOS。)
【解决方案4】:

WWDC 2013 iOS 应用程序使用 WebVTT 文件作为其字幕 (credit to Nicholas Riley for discovering this)。无论出于何种原因,每个会话大约有 50 个(具体数字不同)。

我不知道 AVFoundation 或 MPMoviePlayer 级别是否支持 WebVTT,或者应用程序是否自己下载和解析字幕文件。

快速搜索“webvtt m3u8”会找到对this HTTP Live Streaming Draft 的引用,这表明您也许可以通过简单地引用 m3u8 播放列表中的 WebVTT 文件来完成这项工作。不过,我没有给你举个例子,因为我无法轻易猜出 WWDC 会话的 m3u8 URL。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 1970-01-01
    • 2012-01-03
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多