无法在iOS应用中通过Google投射正确的视频 [英] Can't cast video via google cast correctly in ios app

查看:123
本文介绍了无法在iOS应用中通过Google投射正确的视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在基于AVPlayer使用自定义视频播放器进行项目开发。试图整合Google Cast。我已经基于Google tut进行了集成: https://codelabs.developers。 google.com/codelabs/cast-videos-ios/
但可以迅速转换。投放时,如果视频播放器打开,并且连接了设备(或者从面板连接),一切似乎都可以正常工作,我形成了文件的元信息,并将其传递给了Google投射-一切正常。

I'm working on a project with custom video player, based on AVPlayer. Trying to integrate google cast. I've made integration based on google tuts: https://codelabs.developers.google.com/codelabs/cast-videos-ios/ But with conversion to swift. Everything seems to work fine, when cast, if video player opens, and there is connected device (or if I connect from panel), I form meta info for file, and it's passed to google cast - everything works fine.

但是,我有一个奇怪的行为:
1)开始投射,打开视频,然后是另一个视频,然后是第三个视频。
2)停止投射
3)转到另一个视频,启用投射功能,但它不会开始播放此视频。它开始投射我之前打开的第一个视频。...

But, i have strange behavior: 1) Start casting, open video, then another video, then third video. 2) Stop casting 3) Go to another video, enable casting, but it doesn't start this video. It start casting the first video I opened earlier....

我试图找到清除缓存或队列的任何方法,但是没有。.请帮助

I tried to find any method that clears cache or queue, but there is no.. Please, help

class VideoVC: UIViewController, UIGestureRecognizerDelegate, GCKSessionManagerListener {

var filmTitle: String!
var toPass: String!
var film: MovieDetails!
var filmDetails: Movie!
var sessionManager: GCKSessionManager?
var castSession: GCKCastSession?
var castMediaController: GCKUIMediaController?
var checkPlayed = 0

override func viewDidLoad() {
    super.viewDidLoad()
    sessionManager = GCKCastContext.sharedInstance().sessionManager

    sessionManager?.add(self)

    castMediaController = GCKUIMediaController()
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)


    if let videoURL = toPass {

        if let video = URL(string: videoURL) {
            player = AVPlayer(url: video)

            player.allowsExternalPlayback = true
            player.usesExternalPlaybackWhileExternalScreenIsActive = true

            playerController.player = player
            self.addChildViewController(playerController)
            self.view.addSubview(playerController.view)
            playerController.view.frame = self.view.frame
            self.view.sendSubview(toBack: playerController.view)
        }
    }

    if isCastEnabled() {
        playSelectedItemRemotely()
    }
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)

    player.replaceCurrentItem(with: nil)

}

func buildMediaInformation() -> GCKMediaInformation {
    let metaData = GCKMediaMetadata(metadataType: GCKMediaMetadataType(rawValue: 1)!)

    metaData.setString(filmTitle, forKey: kGCKMetadataKeyTitle)

    if let imageUrl = URL(string: filmDetails.poster_cast!) {
        let image = GCKImage(url: imageUrl, width: 340, height: 450)
        metaData.addImage(image)
    }

    if let episode = film.serial_episode, let season = film.serial_season, season != "", episode != "", let title = film.title, title != "" {
        let subtitle = "\(title) \(episode) серия \(season) сезон"
        metaData.setString(subtitle, forKey: kGCKMetadataKeySubtitle)
    }


    let duration = Double(film.duration!)

    let mediaInfo = GCKMediaInformation(contentID: toPass!,
                                        streamType: GCKMediaStreamType.buffered,
                                        contentType: film.contentType!,
                                        metadata: metaData as GCKMediaMetadata,
                                        streamDuration: duration,
                                        mediaTracks: nil,
                                        textTrackStyle: nil,
                                        customData: nil)

    print("toPass: \(toPass!)")
    print("duration: \(duration)")

    return mediaInfo
}

func playSelectedItemRemotely() {

    let castSession = GCKCastContext.sharedInstance().sessionManager.currentCastSession
    if (castSession != nil) {
        castSession?.remoteMediaClient?.loadMedia(self.buildMediaInformation(), autoplay: true)
        self.dismiss(animated: true, completion: nil)
    }
    else {
        print("no castSession!")
    }
}

func sessionManager(_ sessionManager: GCKSessionManager, didStart session: GCKSession) {
    playSelectedItemRemotely()
}

func sessionManager(_ sessionManager: GCKSessionManager, didResumeSession session: GCKSession) {

}

func sessionManager(_ sessionManager: GCKSessionManager, didEnd session: GCKSession, withError error: Error?) {
    let castSession = GCKCastContext.sharedInstance().sessionManager.currentCastSession
    castSession?.endAndStopCasting(true)
}

func sessionManager(_ sessionManager: GCKSessionManager, didFailToStart session: GCKSession, withError error: Error) {
    Utils.showOverAnyVC("Ошибка подключения", message: "Попробуйте еще раз!")
}

func isCastEnabled() -> Bool {
    switch GCKCastContext.sharedInstance().castState {
    case GCKCastState.connected:
        print("cast connected")
        return true
    case GCKCastState.connecting:
        print("cast connecting")
        return true
    case GCKCastState.notConnected:
        print("cast notConnected")
        return false
    case GCKCastState.noDevicesAvailable:
        print("cast noDevicesAvailable")
        return false
    }
}}

和我的appdelegate:

and my appdelegate:

class AppDelegate:UIResponder,UIApplicationDelegate,GCKLoggerDelegate,UNUserNotificationCenterDelegate {

class AppDelegate: UIResponder, UIApplicationDelegate, GCKLoggerDelegate, UNUserNotificationCenterDelegate {

var window: UIWindow?

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.

    let options = GCKCastOptions(receiverApplicationID: "F443E49F")
    GCKCastContext.setSharedInstanceWith(options)

    GCKLogger.sharedInstance().delegate = self

    let appStoryboard = UIStoryboard(name: "NewMain", bundle: nil)
    let navigationController = appStoryboard.instantiateViewController(withIdentifier: "MainNavigation")
    let castContainerVC: GCKUICastContainerViewController = GCKCastContext.sharedInstance().createCastContainerController(for: navigationController)
    castContainerVC.miniMediaControlsItemEnabled = true
    self.window = UIWindow(frame: UIScreen.main.bounds)
    self.window?.rootViewController = castContainerVC
    self.window?.makeKeyAndVisible()

    GCKCastContext.sharedInstance().useDefaultExpandedMediaControls = true

    return true
}



func logMessage(_ message: String, fromFunction function: String) {
    print("message: \(function)")
}}


推荐答案

可能的解决方案可能是由于:

On possible solution could be due to:

sessionManager?.add(self)

您添加了委托,但您一点都没有清除它。结果,由于会话管理器保留了引用, VideoVC 从未被销毁。当您重新打开 VideoVC 时,会话管理器仍从第一次加载该委托开始就对其进行访问。

You add the delegate but at no point do you clear it. As a result, the VideoVC is never destroyed due to the retained reference from the session manager. When you reopen the VideoVC the session manager is still also accessing the delegate from the first time you loaded it.

因此,在调用以下命令时:

Because of this, when the following is called:

func sessionManager(_ sessionManager: GCKSessionManager, didStart session: GCKSession) {

这是在您的 VideoVC 的第一个实例中调用的

This is being called in your first instance of VideoVC which now has the wrong file information.

您可以通过将print(self)放入上述方法并查看内存指针值来监视此信息。检查它是否也与 viewDidLoad

You can monitor this by putting a print(self) into the above method and look at the memory pointer value. Check that it also matches the same memory pointer value that is called in viewDidLoad

更新中调用的相同的内存指针值匹配>

Update

要更好地管理委托,请更改以下方法: viewDidDisappear()

To better manage the delegate change the following method: viewDidDisappear()

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    player.replaceCurrentItem(with: nil)

    //this stops the session manager sending callbacks to your VideoVC
    sessionManager.remove(self)
}

这篇关于无法在iOS应用中通过Google投射正确的视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆