Last active
February 28, 2022 15:07
-
-
Save habibg1232191/c3bcafb22ffcc17132c1a590f97e6b5c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.compose.foundation.Image | |
import androidx.compose.runtime.* | |
import androidx.compose.ui.graphics.ImageBitmap | |
import androidx.compose.ui.graphics.toComposeImageBitmap | |
import kotlinx.coroutines.delay | |
import org.bytedeco.ffmpeg.avcodec.AVCodecParameters | |
import org.bytedeco.ffmpeg.avutil.AVFrame | |
import org.bytedeco.ffmpeg.global.* | |
import org.bytedeco.ffmpeg.global.avformat.avformat_find_stream_info | |
import org.bytedeco.ffmpeg.global.avformat.avformat_open_input | |
import org.bytedeco.ffmpeg.global.avutil.* | |
import org.bytedeco.ffmpeg.global.swscale.sws_freeContext | |
import org.bytedeco.ffmpeg.swscale.SwsContext | |
import org.bytedeco.javacpp.BytePointer | |
import org.bytedeco.javacpp.DoublePointer | |
import org.bytedeco.javacpp.Loader | |
import org.bytedeco.javacpp.PointerPointer | |
import org.jetbrains.skia.* | |
import java.nio.Buffer | |
@Composable | |
fun MediaPlayer() { | |
val videoUrl by remember { mutableStateOf("<VideoUrl>") } | |
var imageBitmap by remember { mutableStateOf<ImageBitmap?>(null) } | |
LaunchedEffect(Unit) { | |
Loader.load(avutil::class.java) | |
Loader.load(swresample::class.java) | |
Loader.load(avcodec::class.java) | |
Loader.load(avformat::class.java) | |
Loader.load(swscale::class.java) | |
// Register all formats and codecs | |
avcodec.av_jni_set_java_vm(Loader.getJavaVM(), null) | |
avcodec.avcodec_register_all() | |
avformat.av_register_all() | |
avformat.avformat_network_init() | |
Loader.load(avdevice::class.java) | |
avdevice.avdevice_register_all() | |
val pFormatContext = avformat.avformat_alloc_context() | |
avformat_open_input(pFormatContext, videoUrl, null, null) | |
avformat_find_stream_info(pFormatContext, null as PointerPointer<*>?) | |
var pCodecParameters = AVCodecParameters(null) | |
var videoStream = -1 | |
for (i in 0 until pFormatContext.nb_streams()) { | |
val pLocalCodecParameters = pFormatContext.streams(i).codecpar() | |
if(pLocalCodecParameters.codec_type() == AVMEDIA_TYPE_VIDEO) { | |
pCodecParameters = pLocalCodecParameters | |
videoStream = i | |
} | |
} | |
val pCodec = avcodec.avcodec_find_decoder(pCodecParameters.codec_id()) | |
val pCodecContext = avcodec.avcodec_alloc_context3(pCodec) | |
avcodec.avcodec_parameters_to_context(pCodecContext, pCodecParameters) | |
avcodec.avcodec_open2(pCodecContext, pCodec, null as PointerPointer<*>?) | |
val pPacket = avcodec.av_packet_alloc() | |
val pFrame = av_frame_alloc() | |
val pFrameRgb = av_frame_alloc() | |
var imgConvertCtx: SwsContext | |
while(avformat.av_read_frame(pFormatContext, pPacket) >= 0) { | |
val err = avcodec.avcodec_send_packet(pCodecContext, pPacket) | |
val err2 = avcodec.avcodec_receive_frame(pCodecContext, pFrame) | |
if(pPacket.stream_index() == videoStream && err >= 0 && err2 >= 0) { | |
val fmt = pCodecContext.pix_fmt() | |
val info = ImageInfo.makeN32(pFrame.width(), pFrame.height(), ColorAlphaType.OPAQUE) | |
val bm = Bitmap() | |
bm.allocPixels(info, info.minRowBytes) | |
imgConvertCtx = swscale.sws_getContext( | |
pFrame.width(), pFrame.height(), pCodecContext.pix_fmt(), | |
info.width, info.height, fmt, | |
swscale.SWS_BILINEAR, null, null, null as DoublePointer? | |
) | |
// How can I write this in kotlin? | |
// uint8_t* dst[] = { (uint8_t*)bm.pixmap().writable_addr() }; | |
// int dst_stride[] = { SkToInt(bm.pixmap().rowBytes()) }; | |
swscale.sws_scale( | |
imgConvertCtx, pFrame.data(), pFrame.linesize(), 0, | |
pFrame.height(), PointerPointer<AVFrame?>(pFrameRgb), pFrameRgb.linesize() | |
) | |
sws_freeContext(imgConvertCtx) | |
bm.setImmutable() | |
imageBitmap = Image.makeFromBitmap(bm).toComposeImageBitmap() | |
println("Success decode frame") | |
delay(500) | |
} | |
} | |
} | |
imageBitmap?.let { | |
Image( | |
bitmap = it, | |
contentDescription = "Video" | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment