1

Playing Vimeo videos on the web displays close captioning controls like this.

enter image description here

How do I display similar controls on iOS with the Vimeo/PlayerKit?

I've looked high and low but found no documentation on the player kit at all.

SafeFastExpressive
  • 3,637
  • 2
  • 32
  • 39

1 Answers1

1

Since no one else has jumped up with an answer, this is what I've done. Documentation for text tracks in Vimeo/PlayerKit is found in the files Player.swift and RegularPlayer.swift.

From that I constructed a UIButton subclass, CloseCaptionButton, that I display on the video as it plays and allows users to switch tracks.

// A UIAlertAction subclass to pass language code to selected action.
class TaggedAlertAction: UIAlertAction {
    var languageCode: String?

    public convenience init(title: String?, languageCode: String?,  style: UIAlertAction.Style, handler: ((UIAlertAction) -> Void)? = nil) {
        self.init(title: title, style: style, handler: handler)
        self.languageCode = languageCode
    }
}

class CloseCaptionButton: UIButton {
    var languages: [PlayerKit.TextTrackMetadata]?

    func handleTapFrom(vc: UIViewController, videoPlayer: RegularPlayer) {
        guard let languages = languages else { return print("NIL LANGUAGES, Couldn't open language picker") }
        let alert = UIAlertController(title: "Pick Captions Language", message: nil, preferredStyle: .actionSheet)

        // Create an action item in alert for each language.
        languages.forEach({ (textTrack) in
        let languageCode = textTrack.language
        let name = textTrack.title
            alert.addAction(TaggedAlertAction(title: name, languageCode: languageCode, style: .default) { action in
                let identifier = (action as! TaggedAlertAction).languageCode
                self.selectTrackFor(identifier, videoPlayer: videoPlayer)

            })
        })

        // Last action item allows user to turn off captions (or cancel).
        alert.addAction(UIAlertAction(title: "Turn Off Captions", style: .default) { _ in
            videoPlayer.select(nil)
        })
        alert.popoverPresentationController?.sourceView = vc.view
        vc.present(alert, animated: true)
    }

    func selectTrackFor(_ languageCode: String?, videoPlayer: RegularPlayer) {
        guard let languageCode = languageCode else { return print("NIL IDENTIFIER") }
        let matches = videoPlayer.availableTextTracks.filter({ (track) -> Bool in
            return track.language == languageCode
        })
        guard let match = matches.first else {
            return print("No match for language: \(languageCode)")
        }
        videoPlayer.select(match)
    }

    // Configure with player.availableTextTracks
    func configure(_ tracks: [PlayerKit.TextTrackMetadata]) {
        languages = Languages(trackMetadata: tracks)
    }
}

// How to use
closeCaptionButton.configure(videoPlayer.availableTextTracks)

@IBAction func ccButtonTapped(_ sender: Any) {
    closeCaptionButton.handleTapFrom(vc: self, videoPlayer: videoPlayer)
}

Please enjoy!

SafeFastExpressive
  • 3,637
  • 2
  • 32
  • 39
  • Hey there. Two questions please: 1. Are you using AVPlayer directly, PlayerKit provided by vimeo, or embedding vimeo with WKWebView? 2. Overall, is it straight-forward to use vimeo? – om-ha Jan 18 '21 at 22:22
  • 1
    I'm using playerKit provided by Vimeo, but don't recommend it. Since I wrote this the client asked to switch to the native iOS video player, and in doing so I switched to https://github.com/superm0/HCVimeoVideoExtractor, which fetches the Vimeo video URLs to play in AVPlayer. I had to add update it to also decode the text tracks URLs from the Vimeo payload so I could fetch them too. If you don't need the native experience and WkWebView works for your needs I'd probably recommend that. Otherwise the path is through https://github.com/superm0/HCVimeoVideoExtractor – SafeFastExpressive Jan 18 '21 at 23:04
  • So you experimented with PlayerKit (vimeo-wrapped AVPlayer) and that didn't go well. You're interfacing with AVPlayer directly with HCVimeoVideoExtractor. My question is, why didn't you embed the video using WKWebview? or advanced features like Adaptive Bitrate Streaming and Caching are not possible with embedding? – om-ha Jan 18 '21 at 23:57
  • 1
    @om-ha I actually inherited the PlayerKit code, it worked ok for the last 3 years for app without captions. My first enhancement was adding captioning with the code posted here, but I never considered WkWebView because the player was so complex, with a lot of custom features & state. I just wanted to keep it working without breaking features they didn't document (they didn't document anything!). But pretty sure client would not like a web view, they have very specific requirements, first they wanted tons of customization and now want to go fully native with AvPlayerViewController. – SafeFastExpressive Jan 19 '21 at 00:54
  • I can surely relate to that.. the undocumented heritage and overly-picky client. Anyhow, for my case now I am leaning more into using AVPlayer. Just figuring out how to cache HLS stream simultaneously while playing it. With support for Adaptive Bitrate Streaming.. – om-ha Jan 19 '21 at 01:20