西宁市网站设计企业,实时热点新闻事件2023,奥美广告公司简介,济南asp网站制作公司【关键字】
视频提取类Extractor、视频编解码、保存pcm文件 【写在前面】
在使用API6开发HarmonyOS应用时#xff0c;通常会开发一些音视频媒体功能#xff0c;这里介绍如何从视频中提取音频保存到pcm文件功能#xff0c;生成pcm音频文件后#xff0c;就可使用音频播放类… 【关键字】
视频提取类Extractor、视频编解码、保存pcm文件 【写在前面】
在使用API6开发HarmonyOS应用时通常会开发一些音视频媒体功能这里介绍如何从视频中提取音频保存到pcm文件功能生成pcm音频文件后就可使用音频播放类AudioRenderer进行播放了。这里主要介绍从视频提取音频并保存到pcm文件的开发步骤。 【开发步骤】
步骤1对视频格式的文件进行提取音频文件并通过解码器解码并监听获取到的buffer数据直接使用Extractor从视频中提取出来的音频数据不能直接作为类似pcm数据源进行播放需要使用解码器解码之后得到的原始数据才可AudioRenderer进行播放。新建VideoDecoder类在里面封装相关功能代码。使用Extractor从视频提取音频数据并使用解码器解码代码如下
// 可创建VideoDecoder类实现相关功能 private Format format;private Codec decoder;private Extractor extractor;public void createDecoder() {decoder Codec.createDecoder(); // 创建解码器extractor new Extractor(); // 创建Extractor解封装类boolean ret extractor.setSource(new Source(/data/data/com.harmonyospro.myapplication/vedio_audio_test.mp4)); // 设置数据源com.harmonyospro.myapplication为应用包名也可设置为网络视频数据源System.out.println(setSource ret ret);int trackCount extractor.getTotalStreams();//获取轨道for (int i 0; i trackCount; i) {format extractor.getStreamFormat(i);if (format.getStringValue(mime).contains(audio)) { // 视频videoaudio音频/*** tc.steps: step2.set codec format for decoder* tc.expected: step2.the return value is true*/ret decoder.setCodecFormat(format);System.out.println(setCodecFormat ret ret);ret extractor.specifyStream(i);System.out.println(specifyStream ret ret);System.out.println(format.toString() format.toString());System.out.println(format.getStringValue(mine) format.getStringValue(mime));System.out.println(format.getStringValue(width) format.getIntValue(width));System.out.println(format.getStringValue(height) format.getIntValue(height));break;}}decoder.registerCodecListener(listener);}Codec.ICodecListener listener new Codec.ICodecListener() {Overridepublic void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int i) {Format fmt decoder.getBufferFormat(byteBuffer);System.out.println(fmt.toString() fmt.toString());// 写入文件writeFile(byteBuffer,bufferInfo,i);System.out.println(onReadBuffer bufferInfo.toString());}Overridepublic void onError(int errorCode, int act, int trackId) {throw new RuntimeException();}};/*** 调用 start()方法开始解码*/public void start(){boolean start decoder.start();System.out.println(start start);}/*** 调用getAvailableBuffer取到一个可用的ByteBuffer把数据填入ByteBuffer里然后再调用writeBuffer把ByteBuffer写入解码器实例*/public void framebuffer(){int i 1;boolean reachEnd false;while (!reachEnd){extractor.next();//下一帧ByteBuffer dstBuf null;dstBuf decoder.getAvailableBuffer(100000);if (dstBuf null) {try {Thread.sleep(200);} catch (InterruptedException e) {System.out.println(InterruptedException);}continue;}System.out.println(02b dstBuf.toString() dstBuf.toString());BufferInfo bufferInfo new BufferInfo();bufferInfo.offset 0;bufferInfo.size extractor.readBuffer(dstBuf, 0);bufferInfo.timeStamp extractor.getFrameTimestamp();bufferInfo.bufferType extractor.getFrameType();System.out.println(bufferInfo bufferInfo bufferInfo.timeStamp);reachEnd extractor.getStreamId() -1;System.out.println(reachEnd reachEnd);if(reachEnd){bufferInfo.bufferType bufferInfo.BUFFER_TYPE_END_OF_STREAM;}boolean ret decoder.writeBuffer(dstBuf, bufferInfo);System.out.println(writeBuffer ret ret);try {Thread.sleep(200);} catch (InterruptedException e) {System.out.println(InterruptedException);}}} /*** 停止解码释放资源*/public void stopAndRelease(){System.out.println(VedioDecoder stopAndRelease);decoder.stop();decoder.release();}
步骤2封装writeFile方法将获取到的buffer数据写入pcm文件中此处com.harmonyospro.myapplication为工程bundleName可替换为应用包名代码如下
private void writeFile(ByteBuffer outputBuffer, BufferInfo info, int trackId) {FileOutputStream fileOutputStream null;File fd new File(/data/data/com.harmonyospro.myapplication/1.pcm);try {fileOutputStream new FileOutputStream(fd, true);final byte[] chunk new byte[info.size];outputBuffer.get(chunk);fileOutputStream.write(chunk, 0, outputBuffer.limit());outputBuffer.clear();} catch (FileNotFoundException e) {System.out.println(02b FileNotFoundException);} catch (IOException e) {System.out.println(02b IOException);}finally {try {fileOutputStream.close();} catch (IOException e) {System.out.println(IOException);}}
}
步骤3在需要调用视频提取音频的地方进行方法调用代码如下
VideoDecoder videoDecoder new VideoDecoder();
videoDecoder.createDecoder();
videoDecoder.start();
videoDecoder.framebuffer();
//vedioDecoder.stopAndRelease(); // 需要停止的时候停止
这里就完成从视频获取音频并保存到pcm文件的功能了获取到pcm文件就可以使用AudioRenderer进行播放了。 【参考文档】
视频编解码文档https://developer.harmonyos.com/cn/docs/documentation/doc-guides/media-video-codec-0000000000031749
媒体提取开发指导https://developer.harmonyos.com/cn/docs/documentation/doc-guides/media-video-extractor-0000000000044202
音频播放开发指导https://developer.harmonyos.com/cn/docs/documentation/doc-guides/media-audio-playback-0000000000031734