Lukas Anda
09/24/2024, 12:15 PMLukas Anda
09/24/2024, 12:16 PM[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;
};
}]
Lukas Anda
09/24/2024, 12:16 PM@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
}
Lukas Anda
09/24/2024, 12:17 PMBox(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(),
)
}
Johannes Svensson
09/24/2024, 1:54 PMLukas Anda
09/24/2024, 2:30 PMAndrew Watson
10/25/2024, 8:33 PMLukas Anda
10/27/2024, 5:57 PM