0xced / XCDYouTubeKit

YouTube video player for iOS, tvOS and macOS
MIT License
2.92k stars 626 forks source link

Can't play video with cellular network #513

Open tungdangplus opened 3 years ago

tungdangplus commented 3 years ago

I'm really stuck in this too long. But I'm not sure it is an issue of XCDYoutubeKit or not. I just need help. I get the stream URL from XCDYoutubeKit with ONLY (and always) medium quality 360p (I don't know why). The problem is that: when I play long-video (over 1 hour) with the cellular network, the screen is black and no audio. With wifi, it plays pretty well and smooth. I know I need to get the lower quality 240p stream URL to play with cellular. Or maybe, there is another way to play the higher quality with cellular that I didn't know. I appreciate any suggestion or idea. And this is what I get in debug:

2020-12-14 19:52:45.521130-0800 BeeMusic[5237:1471647] [avas] AVAudioSessionUtilities.h:106 AudioSessionGetProperty ('crar') failed with error: '!ini' 2020-12-14 19:52:45.521193-0800 BeeMusic[5237:1471647] [avas] AVAudioSession_iOS.mm:2158 AudioSessionGetProperty failed with code: 560557673

Updated:

SoneeJohn commented 3 years ago

What versions of the library are you running?

tungdangplus commented 3 years ago

What versions of the library are you running?

Hi SoneeJohn, I run v2.15.2. This is one of the video I play https://youtu.be/yF6oimxVIv0 It play good with wifi but not with cellular.

SoneeJohn commented 3 years ago

Can you show me the entire log output?

tungdangplus commented 3 years ago

This is my code:

var xcdOperation: XCDYouTubeOperation?
var avPlayer: AVPlayer?
var avLayer: AVPlayerLayer?
func play (videoTrack: Video, playlist: Playlist){
    xcdOperation = XCDYouTubeClient.default().getVideoWithIdentifier(videoTrack.Id) { (xcdVideo, xcdError) in
        guard xcdVideo != nil || xcdError != nil else {
            self.xcdOperation?.cancel()
            print("Both xcdVideo && xcdError == nil")
            return
        }
            if (xcdVideo != nil) {
                let url0 = xcdVideo?.streamURLs[XCDYouTubeVideoQualityHTTPLiveStreaming]
                let url1 = xcdVideo?.streamURLs[XCDYouTubeVideoQuality.HD720.rawValue]
                let url2 = xcdVideo?.streamURLs[XCDYouTubeVideoQuality.medium360.rawValue]
                let url3 = xcdVideo?.streamURLs[XCDYouTubeVideoQuality.small240.rawValue]

                let qualityLevel: Int = CoreDataLibrary.getSetting().videoQuality ?? 2
                var validUrl : URL?
                switch qualityLevel {
                case 1:
                    validUrl = url1 ?? url2 ?? url3 ?? url0
                case 2:
                    validUrl = url2 ?? url3 ?? url1 ?? url0
                case 3:
                    validUrl = url3 ?? url2 ?? url1 ?? url0
                default:
                    break
                }

                if validUrl == url0 {
                    print("validUrl0")
                } else if validUrl == url1 {
                    print("validUrl1")
                } else if validUrl == url2 {
                    print("validUrl2")
                } else if validUrl == url3 {
                    print("validUrl3")
                } else {
                    print("validUrlNil")
                }

                if let streamUrl = validUrl {
                    self.avPlayer = AVPlayer(url: streamUrl)
                    self.avPlayer?.play()
                    self.avLayer?.player = self.avPlayer

               } else {
                    print("xcdVideo == nil")
               }

            } else {
                print("xcdError", xcdError!.localizedDescription) // Video unavailable
            }

    }//XCDYouTubeClient
}//play()

And debug log when play with cellular network: 2020-12-16 14:44:19.733746-0800 BeeMusic[6516:2036280] 4.13.0 - [Firebase/Analytics][I-ACS023007] Firebase Analytics v.40200000 started 2020-12-16 14:44:19.733884-0800 BeeMusic[6516:2036280] 4.13.0 - [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see http://goo.gl/RfcP7r) AVAudioSession catch error: The operation couldn’t be completed. (OSStatus error 2003329396.) validUrl2 2020-12-16 14:44:46.770697-0800 BeeMusic[6516:2036000] [avas] AVAudioSessionUtilities.h:106 AudioSessionGetProperty ('crar') failed with error: '!ini' 2020-12-16 14:44:46.770734-0800 BeeMusic[6516:2036000] [avas] AVAudioSession_iOS.mm:2158 AudioSessionGetProperty failed with code: 560557673 2020-12-16 14:44:47.189545-0800 BeeMusic[6516:2036000] [avas] AVAudioSessionUtilities.h:106 AudioSessionGetProperty ('crar') failed with error: '!ini' 2020-12-16 14:44:47.189605-0800 BeeMusic[6516:2036000] [avas] AVAudioSession_iOS.mm:2158 AudioSessionGetProperty failed with code: 560557673

SoneeJohn commented 3 years ago

Can you please use the macOS demo app or the iOS demo app and show me the logs from there?

tungdangplus commented 3 years ago

It is a very long log. I attach the log file. When I played the video with your iOS demo app, it played successfully.

XCDYoutubeKit_MacDemo_log.rtf.zip

XCDYoutubeKit_log.rtf.zip

tungdangplus commented 3 years ago

Hi SoneeJohn, it sounds weird but I found the problem as this:

    if let xcdVideo = xcdVideo, let streamURL = xcdVideo.streamURL {
        self.avPlayerItem = AVPlayerItem(url: streamURL)
        self.avPlayer = AVPlayer(playerItem: self.avPlayerItem)
        self.avPlayer?.play()
        self.avLayer?.player = self.avPlayer
    }

the player works well if I don't get the value of '.asset.duration'

 let duration = self.avPlayer?.currentItem?.asset.duration.seconds // getting duration (with .asset.) makes the player stall when play long-video with cellular
print(duration)

I apply this to your iOS Demo app, it happens too. Maybe this is the issue of AVPlayer, not XCDYoutubeKit. Updated: - It can be fixed by calling that value of '.asset.duration' after '.currentItem?.status == .readyToPlay'

tungdangplus commented 2 years ago

What versions of the library are you running?

I run v2.15.2 and it always get 360p