首页 > 编程语言 >【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)

【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)

时间:2023-08-22 14:38:26浏览次数:58  
标签:API6 Java Format System packet 音频文件 println import out


 【关键字】

音频编码、管道模式、createEncoder

【写在前面】

在使用API6开发HarmonyOS应用时,如何将pcm源文件进行编码并写入文件,最后生成aac文件,本文直接附上主要代码开发步骤供大家参考。

【主要功能代码】

import ohos.media.codec.Codec;
import ohos.media.common.BufferInfo;
import ohos.media.common.Format;
import ohos.media.common.Source;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

public class AudioEncoder {

    void creatEncoder(){

    }

    FileOutputStream fileOutputStream = null;

    public void encode(){
        System.out.println("encode start");
        try {
            File fd = new File("/data/data/com.example.myapplication/11.aac");
            fileOutputStream = new FileOutputStream(fd, true);
        } catch (FileNotFoundException e) {
            System.out.println("FileNotFoundException");
        } finally {
        }
        final Codec encoder = Codec.createEncoder();
        String path = "/data/data/com.example.myapplication/11.pcm";
        System.out.println("encoder = " + encoder);
        boolean ret = encoder.setSource(new Source(path), null);
        System.out.println("setSource ret = " + ret);
		
        Format fmt = new Format();
	// format格式中转码率和声道需与pcm相同
        fmt.putStringValue(Format.MIME, Format.AUDIO_AAC);
        fmt.putIntValue(Format.BIT_RATE, 128000);
        fmt.putIntValue(Format.CHANNEL, 2);
        fmt.putIntValue(Format.SAMPLE_RATE, 44100);
        fmt.putIntValue(Format.FRAME_RATE, 30); // 此设置必须,数值一般为30/60,或自行设置需要数值

        boolean b1 = encoder.setSourceFormat(fmt);
        System.out.println("setSourceFormat = " + b1);
        Codec.ICodecListener listener = new Codec.ICodecListener() {
            @Override
            public void onReadBuffer(ByteBuffer byteBuffer, BufferInfo bufferInfo, int trackId) {
                System.out.println("byteBuffer = " + byteBuffer + "trackId = " + trackId + "bufferinfo = " + bufferInfo.bufferType);
                if(bufferInfo.bufferType == 4){
                    encoder.stop();
                    encoder.release();
                    try {
                        fileOutputStream.close();
                    } catch (IOException e) {
			// 打印异常
                        System.out.println("IOException");
                    }
                    return;
                }
                writeFile(byteBuffer,bufferInfo,trackId);

            }
            @Override
            public void one rror(int errorCode, int act, int trackId) {
                System.out.println( "PlayerCallback one rror errorCode: "+errorCode +", trackId:"+trackId);
            }
        };
        boolean b = encoder.registerCodecListener(listener);
        System.out.println("registerCodecListener = " + b);

        boolean start = encoder.start();
        System.out.println("start = " + start);
    }


    private void writeFile(ByteBuffer outputBuffer, BufferInfo info, int trackId) {
        try {
            final byte[] chunk = new byte[info.size+7];
            addADTSHeader(chunk,info.size+7);
            outputBuffer.get(chunk,7,info.size);
            fileOutputStream.write(chunk);
            outputBuffer.clear();
        } catch (FileNotFoundException e) {
            System.out.println("FileNotFoundException");
        } catch (IOException e) {
            System.out.println("IOException");
        } finally {
		
        }
    }
    /**
     * 添加AAC帧文件头
     *
     * @param packet    packet
     * @param packetLen packetLen
     */
    private void addADTSHeader(byte[] packet, int packetLen) {
        int profile = 2; // AAC
        int freqIdx = 4; // 44.1kHz
        int channelCount = 2;//声道
        packet[0] = (byte) 0xFF;
        packet[1] = (byte) 0xF9;
        packet[2] = (byte) (((profile - 1) << 6) + (freqIdx << 2) + (channelCount >> 2));
        packet[3] = (byte) (((channelCount & 3) << 6) + (packetLen >> 11));
        packet[4] = (byte) ((packetLen & 0x7FF) >> 3);
        packet[5] = (byte) (((packetLen & 7) << 5) + 0x1F);
        packet[6] = (byte) 0xFC;
    }
}

【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)_ide

【说明和注意事项】

1、AAC文件有两种添加头文件方式:ADIF与ADTS,此处使用ADTS方式,ADTS是每一段编码都有一个头部,因此并不能只添加一次,需要在回调中添加头文件;添加头文件保存的aac文件可以直接播放;

2、format中需要设置FRAME_RATE,即fmt.putIntValue(Format.FRAME_RATE, 30);,数值必须大于0,否则可能会编码失败

3、编解码功能建议在子线程中执行,不要在主线程中。

【参考文档】

视频编解码文档:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/media-video-codec-0000000000031749


标签:API6,Java,Format,System,packet,音频文件,println,import,out
From: https://blog.51cto.com/u_15687416/7189447

相关文章

  • Java开发的一些小技巧
    编写清晰的代码注释:在关键地方添加合适的注释,使代码更易读、易懂。注释应该解释代码的用途、实现思路或者特殊考虑的地方,帮助其他人理解和维护代码。避免使用魔法数值:将常用的魔法数值定义为常量,以便于理解和维护代码。通过给常量起一个有意义的名称,可以提高代码的可读性和可维护性......
  • javascript学习笔记第五天
    今天的笔记functiongetusergradesum(arr=[])传递数组进入匿名函数,假设不确定数组是否会为空可以默认传一个空的数组进入,这样不会报错在匿名方法里面,return之后就直接结束函数了三元运算符好像不能同时使用两个return,例如i>l?returni:retuenl,这样子会报错return时......
  • 【HarmonyOS】实现将pcm音频文件进行编码并写入文件(API6 Java)
    【关键字】音频编码、管道模式、createEncoder 【写在前面】在使用API6开发HarmonyOS应用时,如何将pcm源文件进行编码并写入文件,最后生成aac文件,本文直接附上主要代码开发步骤供大家参考。 【主要功能代码】importohos.media.codec.Codec;importohos.media.common.Buf......
  • 记录一次在Android Studio中,任务:app:compileDebugJavaWithJavac的执行失败了
    因为我命令行覆盖提交了一次git代码,导致git原本的版本不见了,构建项目的时候提示会找不到SDK排查过程:构建项目时提示找不到SDK目录,经过排查后发现是gitpull的时候没有把local.properties这个文件上传上去,导致后面下载回来的项目都没有,而原本的本地目录被我删了 随机根据最初原始目......
  • Java进阶篇-1
    集合进阶双列集合双列集合的特点:D双列集合一次需要存一对数据,分别为键和值键不能重复,值可以重复键和值是一一对应的,每一个键只能找到自己对应的值键+值这个整体我们称之为“键值对”或者“键值对对象”,在Java中叫做"Entry对象"MAP的常用APIMap<String,String>m=......
  • java实现大文件上传代码
    ​ 这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数下面直接贴代码吧,一些难懂的我大部分都加上注释了:上传文件实体类:看得出来,实体类中已经有很多我们需要的功能了,还有实用的属性。如MD5秒传的信息。pub......
  • 基于JAVA的二手手机回收系统-计算机毕业设计源码+LW文档
    摘要随着信息技术的发展,基于web模式的购物系统逐渐普及,网上购物是一种新型的商务模式,其工作流程和经营模式受到了欢迎。电子商务可以适应现代化快节奏的生活方式,满足各类人群足不出户的在线购物,利用商城使得买卖双方完成线上交易,提高了购买效率。但随着网购二手手机数量的增多,存......
  • 基于JAVA+MySQL技术智能服装推荐系统的设计与实现-计算机毕业设计源码+LW文档
    1.开题依据1.1研究的目的意义在过去到现在,消费方式从物物交换到以通俗认知中的“货币”购买物品,再到如今的网上支付交易,实物物流运输到达我们的手上。购物方式从实体店的消费模式,转到了网上店铺的交易。相信很多人在现实生活中都有过实体店购物的消费的体验,在实体店消费需要安排......
  • 中小学教育综合管理平台源码,vue2+Java+springboot框架开发
    智慧校园电子班牌软件是出于校园考勤管理以及班级校园信息展示为目的的显示系统软件,电子班牌系统主要用于中小学教育的综合管理平台,融合了多媒体技术、语音技术、人脸识别、信息发布、后台管理等多种技术。智慧班牌通过以云平台为基础,结合互联网、物联网系统进行校园管理,实现学校数......
  • Java实现灰度发布的常用方式
    以下内容由GPT3.5生成,仅用于参考并了解基本概念什么是灰度发布灰度发布(GrayDeployment),也称为渐进式发布或金丝雀发布,是一种软件发布策略,用于将新版本的软件或功能逐步引入生产环境,以降低可能出现的问题对整个系统的影响。这种发布方式的核心思想是将新功能或版本仅部分暴......