AVPlayerLayer shows black screen but sound is working
Asked Answered
B

4

5

Im trying to display a local recorded video in a AVPlayerLayer which works sometimes. I can hear the audio from the recorded video but can't see the video. Sometimes both video and audio is working, sometimes only audio.

I've tried both with a AVPlayerLayer and AVPlayerViewController but the same issue occurs in both cases. So it's not because of the frames being wrong.

Example code AVPlayerViewController:

let player = AVPlayer(url: url)
let playerController = AVPlayerViewController()
playerController.player = player

self.present(playerController, animated: true) {
  player.play()
}

Example code AVPlayerLayer:

let asset = AVAsset(url: url)
let item = AVPlayerItem(asset: asset)

self.player = AVPlayer(playerItem: item)
self.player?.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions(), context: nil)
self.playerLayer = AVPlayerLayer(player: self.player!)
self.playerLayer?.frame = imageView.bounds
imageView.layer.addSublayer(self.playerLayer!)

Edit 1:

When observing the status of the player, error is nil and the status is readyToPlay

Edit 2:

Works fine if the URL is remote.

Edit 3:

Seems to work if I wait a couple of seconds after the video has completed the export. Could it be something to have with the file not 100% written to the filesystem?

Edit 4: Video of the problem, in this case it played the 3rd time.

Bullyrag answered 25/11, 2016 at 15:38 Comment(8)
Show the export code.Franchescafranchise
Export code can be found here. pastebin.com/aiSvV6i8Bullyrag
So there are multiple videos?Franchescafranchise
@Franchescafranchise right, multiple videos, exported to one video. And then I'm trying to display the exported video, which works. sometimes.. And if I'm uploading it to our S3 i can perfectly fine view the video.Bullyrag
Yes, I see. And you are waiting until you get cameraDidFinishExportingVideo?Franchescafranchise
@Franchescafranchise yes, when the export is completed I'm closing a ViewController and displaying another one. Which previews the exported video.Bullyrag
Perhaps the problem has to do with how precisely you respond to cameraDidFinishExportingVideo and what you do in the next view controller. But you have not shown any of that.Franchescafranchise
@Franchescafranchise added a video of the problem to the description. Hope it describes the issue better than i did.Bullyrag
E
3

Here's how I set a AVPlayerLayer with the video working (I think what you're missing is the videoGravity parameter).

let bundle = Bundle.main
let moviePath = bundle.path(forResource: "myVideo", ofType: "mp4")
let moviePlayer = AVPlayer(url: URL(fileURLWithPath: moviePath!))

playerLayer = AVPlayerLayer(player: moviePlayer)
playerLayer.frame = movieView.bounds
playerLayer.videoGravity = AVLayerVideoGravityResizeAspect
movieView.layer.addSublayer(playerLayer)
playerLayer.player?.play()
Emden answered 25/11, 2016 at 15:56 Comment(3)
Thanks for the reply, but as I said, it's working sometimes. And always if the video is form a remote URL. And since it's the same issues in the AVPlayerViewController I'm assuming it's not because of that.Bullyrag
Amazingly this seems to have fixed my problem on tvOS. Stranger things happen. :o). Thanks.Obligor
Pls suggest here : #54745859Gouge
L
1

It's the frame height or width is equal to zero

Libre answered 18/1, 2017 at 2:55 Comment(0)
C
1

i have the same issues as you did. the reason is in iOS 10.xx , if you export video with animationTool . You will meet the trouble like that . try to fix them by remove this code .

something like that

 mainComposition.animationTool =  AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentlayer)

Hope to help you

Console answered 7/6, 2018 at 8:6 Comment(0)
T
0

What caused this issue for me was I was changing assets to play a new video. The problem was I was reinitializing the same AVPlayer and setting setting it to the playerLayer which was previously set

Incorrect

player = AVPlayer()
playerLayer = AVPlayerLayer(player: player)
// ...
player?.replaceCurrentItem(with: playerItem)

Correct

if player == nil {

    player = AVPlayer()
    playerLayer = AVPlayerLayer(player: player)
    // ...
}

player?.replaceCurrentItem(with: playerItem)

Or better yet I should've just called this by itself

player?.replaceCurrentItem(with: playerItem)
Turro answered 19/3, 2022 at 6:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.