【HarmonyOS】实现从视频提取音频并保存到pcm文件功能(API6 Java)

这篇具有很好参考价值的文章主要介绍了【HarmonyOS】实现从视频提取音频并保存到pcm文件功能(API6 Java)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 【关键字】

视频提取类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")) { // 视频video,audio音频
              /**
               * @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() {
      @Override
      public 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());
      }

      @Override
      public 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文章来源地址https://www.toymoban.com/news/detail-605519.html

到了这里,关于【HarmonyOS】实现从视频提取音频并保存到pcm文件功能(API6 Java)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【音视频 | wav】wav音频文件格式详解——包含RIFF规范、完整的各个块解析、PCM转wav代码

    😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭 🤣本文内容🤣:🍭介绍wav音频格式🍭 😎金句分享😎:🍭子曰:父母在,不远游,游必有方。 ——《论语·里仁篇》。意思是,父母还健在时,就不要

    2024年02月06日
    浏览(59)
  • 提取视频文件里的音频和无声视频

    一、提取视频文件里的音频: 二、提取视频文件里的无声视频

    2024年02月11日
    浏览(39)
  • Vue实现前端视频展示列表及特征提取、笔记、删除、文件夹组织功能

    Vue实现前端视频展示列表及特征提取、笔记、删除、文件夹组织功能 在前端展示上传的视频列表时,我们可以使用Element-UI中的Card组件来实现。同时,我们还可以添加一些功能,如缓存播放的视频、选择视频文本特征提取处理、写笔记、删除视频、组织成文件夹结构等。下面

    2024年02月10日
    浏览(53)
  • 使用ffmpeg从视频文件中提取音频文件、视频抽帧和切割视频

    目录 ffmpeg下载 使用ffmpeg从视频文件中提取音频文件 批量提取文件夹下多个视频文件的音频 使用ffmpeg从视频文件中提取视频帧 使用ffmpeg将按固定时长将视频切割成多个小片段 将分割得到的视频存放在新建文件夹下(这个我运行的时候好像有点问题,音频文件没有存放在新建

    2023年04月08日
    浏览(59)
  • 怎么视频提取音频文件?分享这3种简单实用的提取方法

    不知道大家平时用手机刷视频的时候,会不会被一些好听的背景音乐给吸引了呢?这些背景音乐大多都是网友们自己合成导入视频上传的,可能在许多音乐平台都不能找到音源播放。遇到这样的情况,大家一定都很苦恼吧?但其实,我们可以使用一些软件将视频中的音频提取

    2023年04月09日
    浏览(43)
  • 音视频 ffmpeg命令提取PCM数据

    提取PCM 推荐一个零声学院项目课,个人觉得老师讲得不错,分享给大家: 零声白金学习卡(含基础架构/高性能存储/golang云原生/音视频/Linux内核) https://xxetb.xet.tech/s/VsFMs

    2024年02月09日
    浏览(59)
  • 通过python如何实现视频提取音频,并将音频转文本

    大致思路: (1)使用moviepy库中的VideoFileClip类读取视频文件,并将其转换为音频文件; (2)使用pydub库中的splitonsilence函数将音频文件分割成多个音频片段,以便进行语音识别; (3)使用SpeechRecognition库中的Recognizer类进行语音识别,并将识别结果写入文本文件中 注意: 将

    2024年02月05日
    浏览(72)
  • Java Mp3转化WAV/PCM音频数据,解码详细解析,提取每一帧数据集合/比特流/播放,一行代码!

    大家好!我是原子君 1 .因为Java本身只支持,wav,缺少mp3的解码器,所以Java自带的无法对mp3进行处理,这种 MPEG-*音频有损压缩标准编码 ,更不要说使用Java的音频格式和音频流就可以解决。 2 .所以本次转换需要使用到colorful1.1这种纯Java-Pc可跨平台的工具框架。 注意:colorful只支持

    2024年02月15日
    浏览(50)
  • HarmonyOS实战开发-录音机、如何实现音频录制和播放的功能

    本示例使用audio相关接口实现音频录制和播放的功能,使用mediaLibrary实现音频文件的管理。 相关概念: AudioRecorder:音频录制的主要工作是捕获音频信号,完成音频编码并保存到文件中,帮助开发者轻松实现音频录制功能。它允许调用者指定音频录制的采样率、声道数、编码

    2024年04月17日
    浏览(113)
  • 安卓音视频开发(3)—— AudioTrack两种方式播放pcm音频

    前言 之前学习了AudioRecord录制pcm音频,与之对应的就是AudioTrack播放pcm音频(MediaPlayer、SoundPool有其他应用场景),它有两种数据加载模式(MODE_STATIC、MODE_STREAM)。 模式 MODE_STATIC :这种模式下,一次将所有的数据放入一个固定的buffer,然后写入到AudioTrack中,后续就不用继续

    2023年04月22日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包