当前位置: 首页 > news >正文

丝网外贸做哪些网站最优的赣州网站建设

丝网外贸做哪些网站,最优的赣州网站建设,运营招聘,jsp做电影网站文章目录 背景解决过程曲线修复方案 解决问题根源 背景 最近在测试视频录制功能时发现#xff0c;AudioRecord MediaCodec MediaMuxer生成的MP4#xff0c;PC浏览器无法播放 #xff0c;但是Android、Windows、Mac的播放器应用都能正常播放。虽然不禁想吐槽浏览器视频组件… 文章目录 背景解决过程曲线修复方案 解决问题根源 背景 最近在测试视频录制功能时发现AudioRecord MediaCodec MediaMuxer生成的MP4PC浏览器无法播放 但是Android、Windows、Mac的播放器应用都能正常播放。虽然不禁想吐槽浏览器视频组件的容错性差但我也意识生成的文件格式肯定也是有问题的。 然后尝试了合成MP4视频时只保留视频通道不要音频发现拖到浏览器中可以正常播放。使用ffprobe检查有问题的MP4文件有如下错误输出 [aac 0x7f95c9c0e7c0] Input buffer exhausted before END element found至此基本确定问题出现在生成的音频数据上。 解决过程 由于此前个人音视频开发经验不足MediaCodec、MediaMuxer编码和合成视频的相关代码参考了一些开源项目及博客。 但由于开发周期紧急没有足够的时间来仔细研究和排查当时就采用了一种曲线救国的方案。 曲线修复方案 能想到这个方案也比较偶然。当时查阅了一些资料和博客用到了ffmpeg和ffprobe工具对问题视频进行分析。 在尝试了使用ffmpeg工具对问题视频进行转换后意外地发现虽然命令也会报错[aac 0x7f95c9c0e7c0] Input buffer exhausted before END element found但是问题视频经过fmpeg转换后生成的新视频用ffprobe命令查看是没有错误输出的也可以正常播放也就是说ffmpeg在处理转换有问题的音频时会自动跳过那些有问题的数据。 由此想到了一个比较曲折的方案先用AudioRecord MediaCodec MediaMuxer生成MP4然后使用ffmpeg命令对生成的视频进行一点无关紧要的转换重点是让它处理掉有问题的数据然后就能得到一个格式正确的音频数据然后用MediaExtractor提取出原MP4中的视频数据最后用MediaMuxer合成最终格式正确的mp4文件。 因为是音频有问题所以实践中我就使用了如下命令来转换 ffmpeg -i input.mp4 -vn -ab 96k out.m4a-vn参数指定不要视频数据-ab 96k将音频码率转为96k。 现在只需要裁剪、交叉编译一个满足以上需求的arm版本的ffmpeg可执行程序就好了。关于如何裁剪和编译ffmpeg网上音视频相关的技术文章一大把就不赘述细节了。 这里记录一下我反复测试编译配置参数后能输出较小体积约2.6MBarm版ffmpeg可执行命令的编译脚本方便以后查看。因为我只需要处理音频所以这个配置编译出的ffmpeg只能解码MP4和aac并且只支持输出m4a音频。 #!/bin/sh# NDK路径根据电脑环境配置情况调整 NDK_HOME/Users/shenyong/Library/Android/sdk/ndk/21.4.7075529 TOOLCHAIN$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64 SYSROOT$TOOLCHAIN/sysroot# 默认使用arm编译配置 API29 ARCHarm CPUarmv7-a TOOL_CPU_NAMEarmv7a # CROSS_PREFIX, CC and CXX for arm CROSS_PREFIX$TOOLCHAIN/bin/arm-linux-androideabi- CC$TOOLCHAIN/bin/$TOOL_CPU_NAME-linux-androideabi$API-clang CXX$TOOLCHAIN/bin/$TOOL_CPU_NAME-linux-androideabi$API-clang OUTPUT_DIR./android/$CPU OPTIMIZE_CFLAGS-march$CPUfunction config_arm64() {ARCHarm64CPUarmv8-aTOOL_CPU_NAMEaarch64# CROSS_PREFIX, CC and CXX for arm64CROSS_PREFIX$TOOLCHAIN/bin/$TOOL_CPU_NAME-linux-android-CC$TOOLCHAIN/bin/$TOOL_CPU_NAME-linux-android$API-clangCXX$TOOLCHAIN/bin/$TOOL_CPU_NAME-linux-android$API-clangOUTPUT_DIR./android/$CPUOPTIMIZE_CFLAGS-march$CPU#libmediandk.so路径MEDIA_NDK_LIB$TOOLCHAIN/sysroot/usr/lib/aarch64-linux-android/$APIADD_MEDIA_NDK_SO--extra-ldflags-L$MEDIA_NDK_LIB --extra-libs-lmediandk }# 如果需要编译arm64版本将以下行取消注释即可 config_arm64#清除之前的编译配置及输出 make distclean./configure \ --prefix$OUTPUT_DIR \ --target-osandroid \ --arch$ARCH \ --cpu$CPU \ --enable-cross-compile \ --cross-prefix$CROSS_PREFIX \ --sysroot$SYSROOT \ --cc$CC \ --cxx$CXX \ --extra-cflags-Os -fpic $OPTIMIZE_CFLAGS \ --disable-shared \ --enable-static \ --enable-neon \ --disable-asm \ --disable-gpl \ --disable-postproc \ --enable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --disable-avdevice \ --disable-doc \ --disable-symver \ --disable-protocols \ --enable-protocolfile \ --disable-network \ --disable-jni \ --disable-mediacodec \ --disable-hwaccels \ --disable-encoders \ --enable-encoderaac \ --disable-decoders \ --enable-decoderaac \ --enable-decodermpeg4 \ --disable-muxers \ --enable-muxeripod \ --disable-demuxers \ --enable-demuxeraac \ --enable-demuxermpegvideo \ --enable-demuxermov \ --disable-parsers \ --enable-parseraac \ --enable-parsermpeg4video \ --enable-parsermpegaudio \ --disable-filters \ --disable-bsfs \ --enable-bsfaac_adtstoascmake clean make -j12 make install解决问题根源 既然自己分析找不到问题根源就看看别人正常工作的代码有什么不一样吧于是开始在GitHub上找相似功能的开源库。在运行AudioVideoRecordingSample这个演示库后发现别人生成的视频和音频用ffprobe命令检查格式都是正确的。 仔细分析对比后终于找到了问题点。网上各种博客的示例代码中都是在dequeueOutputBuffer()返回的输出buffer下标大于0时就直接写入Muxer关键部分类似这样 int outputBufferIndex mAudioCodec.dequeueOutputBuffer(bufferInfo, 0); if (outputBufferIndex MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {// 将mMediaCodec的指定的格式的数据轨道设置到mMediaMuxer上mAudioTrackIndex mMediaMuxer.addTrack(mAudioCodec.getOutputFormat());// ... } else {while (outputBufferIndex 0) {// 获取数据ByteBuffer outBuffer mAudioCodec.getOutputBuffers()[outputBufferIndex];audioPts (System.nanoTime() - startNanoTime) / 1000;bufferInfo.presentationTimeUs audioPts;// 编码数据写入muxermMediaMuxer.writeSampleData(mAudioTrackIndex, outBuffer, bufferInfo);// 释放 outBuffermAudioCodec.releaseOutputBuffer(outputBufferIndex, false);outputBufferIndex mAudioCodec.dequeueOutputBuffer(bufferInfo, 0);} }但是我发现AudioVideoRecordingSample这个库在获取的outputBufferIndex 0时还有一个关键的处理 // ... if ((mBufferInfo.flags MediaCodec.BUFFER_FLAG_CODEC_CONFIG) ! 0) {// You shoud set output format to muxer here when you target Android4.3 or less// but MediaCodec#getOutputFormat can not call here(because INFO_OUTPUT_FORMAT_CHANGED dont come yet)// therefor we should expand and prepare output format from buffer data.// This sample is for API18(Android 4.3), just ignore this flag hereif (DEBUG) Log.d(TAG, drain:BUFFER_FLAG_CODEC_CONFIG);mBufferInfo.size 0; } if (mBufferInfo.size ! 0) {// ...muxer.writeSampleData(mTrackIndex, encodedData, mBufferInfo); } /// ...就是判断当前的mBufferInfo有BUFFER_FLAG_CODEC_CONFIG这个标志时把size置为0了所以这一次回调的数据是没有写入muxer的。于是赶紧看了一眼BUFFER_FLAG_CODEC_CONFIG的官方文档 /*** This indicated that the buffer marked as such contains codec* initialization / codec specific data instead of media data.*/public static final int BUFFER_FLAG_CODEC_CONFIG 2;这才恍然大悟当BufferInfo有这个标志的时候buffer包含编解码器初始化或编解码器特定的数据而不是媒体数据 于是在自己的代码中也上这个判断处理生成的视频文件再用ffprobe查看也能正常输出信息没有报错了。关键代码如下 while (true) {try {// 返回有效数据填充的输出缓冲区的索引int outputBufferIndex mAudioCodec.dequeueOutputBuffer(bufferInfo, 0);if (outputBufferIndex MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {// 将mMediaCodec的指定的格式的数据轨道设置到mMediaMuxer上mAudioTrackIndex mMediaMuxer.addTrack(mAudioCodec.getOutputFormat());} else {while (outputBufferIndex 0) {// 获取数据ByteBuffer outBuffer mAudioCodec.getOutputBuffers()[outputBufferIndex];// 修改音频的 pts,基准时间戳audioPts (System.nanoTime() - startNanoTime) / 1000;bufferInfo.presentationTimeUs audioPts;if ((bufferInfo.flags MediaCodec.BUFFER_FLAG_CODEC_CONFIG) ! 0) {Log.w(TAG, audio BUFFER_FLAG_CODEC_CONFIG bufferInfo.size: bufferInfo.size);// 配置回调不是有效的媒体数据不写入。如果写入了会导致mp4文件有错误数据帧// 容错性不够好的播放器比如pc浏览器可能无法正常播放视频。bufferInfo.size 0;}// 写入音频数据if (bufferInfo.size 0) {mMediaMuxer.writeSampleData(mAudioTrackIndex, outBuffer, bufferInfo);}if ((bufferInfo.flags MediaCodec.BUFFER_FLAG_END_OF_STREAM) ! 0) {Log.w(TAG, audio BUFFER_FLAG_END_OF_STREAM bufferInfo.size: bufferInfo.size);}// 释放 outBuffermAudioCodec.releaseOutputBuffer(outputBufferIndex, false);if ((bufferInfo.flags MediaCodec.BUFFER_FLAG_END_OF_STREAM) ! 0) {Log.w(TAG, audio got BUFFER_FLAG_END_OF_STREAM flag. audioPts: bufferInfo.presentationTimeUs bufferInfo.size: bufferInfo.size);if (shouldExit) {onDestroy();return;}}outputBufferIndex mAudioCodec.dequeueOutputBuffer(bufferInfo, 0);}}} catch (Exception e) {e.printStackTrace();} }这样一来使用MediacodecMuxer就能生成格式正确的mp4视频文件了无需其他处理效率大大提高。 从打印日志来看带这个标志的一般就是第一个输出的buffer并且数据量很少 2023-09-21 10:16:36.664 BaseVid...corder W audio BUFFER_FLAG_CODEC_CONFIG bufferInfo.size: 2 2023-09-21 10:16:36.675 BaseVid...corder W video BUFFER_FLAG_CODEC_CONFIG bufferInfo.size: 30最后经过测试验证也确实是这样的 只要bufferInfo有BUFFER_FLAG_CODEC_CONFIG标志时把buffer数据写入muxer了用ffprobe查看生成的视频文件就一定会有[aac 0x7f95c9c0e7c0] Input buffer exhausted before END element found这个错误输入反之不写入就是正常的。
http://www.w-s-a.com/news/960525/

相关文章:

  • 如何做网站不被查网站开发工程师岗位说明书
  • 做网站需要vps吗网站建设后怎样发信息
  • 网站建立风格二手交易网站开发可参考文献
  • 成都微信网站开发优化大师优化项目有哪些
  • 哪个网站做自考题目免费郑州网站建设公司qq
  • 地方性的网站有前途顺的网络做网站好不好
  • 学校申请建设网站的原因不要网站域名
  • 推荐响应式网站建设子域名查询工具
  • 如何建设学校的微网站广告推广是什么
  • 设计类专业哪个就业前景好网站建设seoppt
  • 济南建站公司网站网站友链查询源码
  • 校园失物招领网站建设涪陵网站建设公司
  • 怎么做盗号网站手机网站建设需要租用什么科目
  • 成品网站是什么意思沈阳seo推广
  • 购物网站后台流程图昆明官网seo技术
  • 创建自己网站全网零售管理系统
  • 江苏省建设厅网站建筑电工证wordpress收费插件大全
  • 北京中国建设银行招聘信息网站宁德蕉城住房和城乡建设部网站
  • 泉州做网站优化哪家好wordpress站点预览
  • 创建门户网站一页网站首页图如何做
  • 服装手机商城网站建设sns社交网站有哪些
  • 无锡工程建设招标网站怎么自己建设公司网站
  • 哪个网站可以学做咸菜安卓软件开发需要学什么软件
  • 自有网站建设的团队遂宁市建设局网站
  • 网站建设哪个好一些网站内容导出
  • 什么网站的页面做的比较好看网上做平面设计的网站
  • 网站建设单选网站建设学校培训学校
  • 可以做app的网站logo设计在线生成免费标小智
  • 网站变更备案做酒类网站
  • 网站必须要备案吗东莞市非凡网站建设