Hey all, I'm trying to play a video using AVPlayer...
# compose-ios
l
Hey all, I'm trying to play a video using AVPlayer and pass to it a video composition created in Kotlin but it renders as a black screen. The asset itself it playing (I can hear the sound) but the rendering then is incorrect I guess. What am I doing wrong? The code is in the 🧵 Also, the asset itself (if I don't pass in the composition) is playing correctly
These are the instructions I created:
Copy code
[AVVideoCompositionInstruction {
    EndTime =     {
        epoch = 0;
        flags = 1;
        timescale = 1000;
        value = 9508;
    };
    LayerStack =     (
                {
            ConstantAffineMatrix =             (
                1,
                0,
                0,
                1,
                0,
                0
            );
            ConstantCropRectangle =             {
                Height = 1080;
                Width = 1920;
                X = 0;
                Y = 0;
            };
            ConstantOpacity = 1;
            SourceVideoTrackID = 1;
        }
    );
    StartTime =     {
        epoch = 0;
        flags = 1;
        timescale = 30;
        value = 0;
    };
}]
This is how the composition is created:
Copy code
@OptIn(ExperimentalForeignApi::class)
fun setupSimpleVideoComposition(asset: AVAsset): AVMutableVideoComposition {
    val videoTrack = asset.tracksWithMediaType(AVMediaTypeVideo).first() as AVAssetTrack

    Logger.e("TAG") {"Track id: ${videoTrack.trackID}"}

    // Create a basic video composition
    val videoComposition = AVMutableVideoComposition()
    videoComposition.setFrameDuration(CMTimeMake(value = 1, timescale = 30))
    videoComposition.setRenderSize(asset.naturalSize)

    // Create a simple instruction
    val instruction = AVMutableVideoCompositionInstruction()
    instruction.setTimeRange(CMTimeRangeMake(start = CMTimeMake(0, 30), duration = asset.duration))

    // Create a layer instruction without any transformations
    val layerInstruction = videoCompositionLayerInstructionWithAssetTrack(videoTrack)
    layerInstruction.setCropRectangle(CGRectMake(0.0, 0.0, 1920.0, 1080.0), CMTimeMake(0, 30))
    layerInstruction.setTrackID(videoTrack.trackID)
    layerInstruction.setTransform(cValue { CGAffineTransformIdentity }, CMTimeMake(0, 30))
    instruction.setLayerInstructions(listOf(layerInstruction))

    // Add the instruction to the video composition
    videoComposition.setInstructions(listOf(instruction))

    return videoComposition
}
And this is the video player:
Copy code
Box(modifier) {
        val player = remember { AVPlayer() }
        LaunchedEffect(compositionWrapper) {
            val item = AVPlayerItem(compositionWrapper.asset).apply {
                val composition = setupSimpleVideoComposition(compositionWrapper.asset)
                Logger.e("TAG") { "Frames: ${CMTimeGetSeconds(composition.frameDuration)}" }
                Logger.e("TAG") { "Instructions: ${composition.instructions}" }
                setVideoComposition(composition)
            }
            Logger.e("TAG") { "Duration: ${CMTimeGetSeconds(item.duration)}" }
            player.replaceCurrentItemWithPlayerItem(item)
        }
        val playerLayer = remember { AVPlayerLayer() }
        val avPlayerViewController = remember { AVPlayerViewController() }
        avPlayerViewController.player = player
        avPlayerViewController.showsPlaybackControls = true
        avPlayerViewController.videoGravity = AVLayerVideoGravityResizeAspectFill

        playerLayer.player = player
        playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
        UIKitView(
            factory = {
                val playerContainer = UIView()
                playerContainer.addSubview(avPlayerViewController.view)
                playerContainer
            },
            onResize = { view: UIView, rect: CValue<CGRect> ->
                CATransaction.begin()
                CATransaction.setValue(true, kCATransactionDisableActions)
                view.layer.setFrame(rect)
                playerLayer.setFrame(rect)
                avPlayerViewController.view.layer.frame = rect
                CATransaction.commit()
            },
            update = {
                player.play()
                avPlayerViewController.player?.play()
            },
            modifier = Modifier.fillMaxSize(),
        )
    }
j
Are you using CMP 1.7.0-beta01 or later?
l
Still on 1.7.0-alpha02 but I know about thw switch from UIView to the new stuff. Also, it turns out it was simulator issue.
👍 1
a
Hey what is the new way to do this? I just bumped to 1.7 and am seeing odd stuff with rendering size
l
basically you resize in update