HarmonyOS鸿蒙Next中实现音视频录制功能示例代码

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS鸿蒙Next中实现音视频录制功能示例代码

介绍

本示例基于AVRecorder实现音视频录制,包括开始录制、暂停、结束、上一个等几乎所有录制音视频的基本操作。

实现音视频录制功能源码链接

效果预览

图片名称

使用说明

  • 打开应用,展示视频录制和音频录制两个按钮。
  • 点击视频录制即可录制视频,并会保存视频。点击音频录制按钮即可开始录制音频,并会保留音频文件,点击文件可以进行播放。

实现思路

构建音频录制页面

  1. 构造setAudioRecorderCallback()函数,用于为音频录制相关的对象(this.avRecorder)设置回调函数,以处理音频录制过程中出现的状态变化以及错误上报这两种情况。通过注册对应的回调函数,使得在相应事件发生时能够执行特定的日志记录操作,方便后续对音频录制状态进行监控和错误排查。
if (this.avRecorder != undefined) {
   // 状态机变化回调函数
   this.avRecorder.on('stateChange', (state: media.AVRecorderState, reason: media.StateChangeReason) => {
   })
   // 错误上报回调函数
   this.avRecorder.on('error', (err: BusinessError) => {
   })
}
  1. 构造getFile()函数,用以获取一个文件对象(fs.File类型),用于后续对文件进行读写等操作。它通过调用 fs.openSync 函数,按照指定的模式(可读可写且若文件不存在则创建)打开一个特定路径下的文件,并返回这个打开后的文件对象。
let file: fs.File = fs.openSync(fileUri.getUriFromPath(this.filesDir + '/Audio_' + new Date().getTime() + '.mp3'), fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
return file;
  1. 构造startRecordingProcess()函数,用于实现音频录制的完整启动流程。涵盖从创建音频录制实例、设置相关回调、获取录制文件描述符并配置录制参数,到最终启动录制的一系列操作,并且对过程中可能出现的错误进行基本的捕获和日志记录处理。
async startRecordingProcess() {
   if (this.avRecorder == undefined) {
     this.avRecorder = await media.createAVRecorder();
   }

   this.setAudioRecorderCallback();
   this.curFile = this.getFile();
   this.avConfig.url = 'fd://' + this.curFile.fd;
   await this.avRecorder.prepare(this.avConfig);
   this.textTimerController.start()
   await this.avRecorder.start();
   this.recordFlag = true;
}
  1. 构造pauseRecordingProcess()函数,主要用于暂停正在进行的音频录制过程。首先判断音频录制实例是否存在且当前处于 “started”(已开始)状态,只有满足这一前提条件时,才会执行暂停相关的操作,包括设置继续标志、暂停相关的计时器以及调用音频录制实例的暂停方法。
async pauseRecordingProcess() {
   if (this.avRecorder != undefined && this.avRecorder.state === 'started') { 
     this.continueFlag = false;
     this.textTimerController.pause()
     await this.avRecorder.pause();
   }
}
  1. 构造resumeRecordingProcess()函数,主要负责在音频录制处于暂停状态时将其恢复继续进行。首先对音频录制实例的存在性以及当前所处的暂停状态进行判断,只有满足相应条件,才会执行后续恢复录制的相关操作,比如更新继续标志、重启相关计时器以及调用音频录制实例的恢复方法。
async resumeRecordingProcess() {
   if (this.avRecorder != undefined && this.avRecorder.state === 'paused') { 
     this.continueFlag = true;
     this.textTimerController.start()
     await this.avRecorder.resume();
   }
}
  1. 构造stopRecordingProcess()函数,用于完成音频录制停止的一系列相关操作,涵盖了停止当前正在进行或处于暂停状态的录制、重置相关状态和组件、释放录制实例资源以及关闭用于录制的文件描述符等操作,整体实现了音频录制结束后的资源清理和状态复位功能。
async stopRecordingProcess() {
   if (this.avRecorder != undefined) {

     if (this.avRecorder.state === 'started'
       || this.avRecorder.state === 'paused') { 
       await this.avRecorder.stop();
     }

     this.recordFlag = false;
     await this.avRecorder.reset();
     this.textTimerController.reset();

     await this.avRecorder.release();

     fs.closeSync(this.curFile)
     this.avRecorder = undefined;
   }
}

视频录制页面的实现

  1. 构造startCameraOutput()函数,用以启动视频输出相关操作,具体是通过调用 VideoOutput 实例(由 this.videoOutput 表示)的 start 接口来开启录像输出功能,并且对调用过程中可能出现的错误进行了基本的捕获与日志记录处理。
async startCameraOutput() {
   // 调用VideoOutput的start接口开始录像输出
   if (this.videoOutput !== undefined) {
     try {
       await this.videoOutput.start();
     } catch (error) {
       let err = error as BusinessError;
       logger.error(`AVRecorderVideoDemo videoOutput start error: ${JSON.stringify(err)}`);
     }
   }
}
  1. 构造stopCameraOutput()函数,调用 VideoOutput 实例(通过 this.videoOutput 表示)的 stop 接口,以此来停止录像输出操作,同时对执行过程中可能出现的错误进行了捕获,并记录相应的错误日志,方便后续排查问题。
async stopCameraOutput() {
   // 调用VideoOutput的stop接口停止录像输出
   if (this.videoOutput !== undefined) {
     try {
       await this.videoOutput.stop();
     } catch (error) {
       let err = error as BusinessError;
       logger.error(`AVRecorderVideoDemo videoOutput stop error: ${JSON.stringify(err)}`);
     }
   }
}
  1. 启动画中画:调用pipController.startPiP()可以开启画中画,在开启前可以设置返回桌面时是否自动启动画中画pipController.setAutoStartEnabled(true/false)
startPipWindow() {
   if (this.pipController) {
     this.pipController.setAutoStartEnabled(true)
     this.pipController.startPiP().then(() => {
       ···
     });
   }
}
  1. 构造releaseCamera()函数,用于释放相机相关的各类资源,涵盖相机会话、相机输入流、预览输出流以及录像输出流等方面。通过一系列的条件判断与对应资源释放操作,并对每个操作中可能出现的错误进行捕获和记录日志,以此来确保相机相关资源能被妥善清理,避免资源泄漏等问题。
async releaseCamera() {
   // 释放相机准备阶段创建出的实例
   // 1、停止当前会话
   if (this.cameraSession !== undefined) {
     try {
       await this.cameraSession.stop();
     } catch (error) {
       let err = error as BusinessError;
       logger.error(`AVRecorderVideoDemo cameraSession stop error: ${JSON.stringify(err)}`);
     }
   }
   ···
}
  1. 构造startRecordingProcess()函数,实现启动录制的完整流程。涵盖创建录制实例、准备相机相关工作、启动相机输出流以及正式启动录制等关键操作,同时对整个过程中可能出现的错误进行了捕获,并记录相应的错误日志,方便后续排查问题。
async startRecordingProcess() {
   try {
     if (this.avRecorder === undefined) {
       // 1、创建录制实例
       await this.createAVRecorder();
       // 2.完成相机相关准备工作
       await this.prepareCamera();
     }

     if (this.avRecorder !== undefined) {
       // 3.启动相机出流
       // await this.startCameraOutput();
       // 4. 启动录制
       if (this.avRecorder.state === 'prepared') {
         await this.avRecorder.start();
       }
       this.textTimerController.start();
       this.recording = true;
       this.pausing = false;
       this.isFinished = false;
     }
   }
}
  1. 构造prepareCamera()函数,主要负责相机相关的一系列准备工作,涵盖获取相机设备信息、设置音视频录制参数、创建各种相机相关的输入输出流、配置相机会话以及启动会话和相关输出流等诸多操作,同时对各个操作过程中可能出现的错误进行捕获与日志记录,以此保障相机准备工作能尽可能顺利完成,为后续的录制等操作奠定基础。
async prepareCamera() {
   if (!this.cameraManager || !this.avRecorder) {
     logger.error('AVRecorderVideoDemo cameraManager is undefined or avRecorder is undefined.')
     return;
   }
   // 获取支持指定的相机设备对象
   let cameraDevices: Array<camera.CameraDevice> = [];
   try {
     cameraDevices = this.cameraManager.getSupportedCameras();
   } catch (error) {
     let err = error as BusinessError;
     logger.error(`AVRecorderVideoDemo The getSupportedCameras call failed. error: ${JSON.stringify(err)}`)
   }

}

更多关于HarmonyOS鸿蒙Next中实现音视频录制功能示例代码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

显示屏幕黑屏,没找到问题出在哪里

更多关于HarmonyOS鸿蒙Next中实现音视频录制功能示例代码的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


开发者您好,您的问题已收到,我们的研发人员正在处理中,请耐心等待。

开发者您好,我们的研发人员使用真机测试未复现问题,若未解决,请您详细描述问题情况,感谢您的支持。

在HarmonyOS鸿蒙Next中实现音视频录制功能,可以使用AVRecorder类。以下是一个简单的示例代码,展示如何实现音视频录制:

import media from '@ohos.multimedia.media';
import fileIO from '@ohos.fileio';

// 创建AVRecorder实例
let avRecorder = await media.createAVRecorder();

// 配置录制参数
let avProfile = {
    audioBitrate: 48000,
    audioChannels: 2,
    audioCodec: media.CodecMimeType.AUDIO_AAC,
    audioSampleRate: 44100,
    fileFormat: media.ContainerFormatType.CFT_MPEG_4,
    videoBitrate: 1000000,
    videoCodec: media.CodecMimeType.VIDEO_AVC,
    videoFrameWidth: 640,
    videoFrameHeight: 480,
    videoFrameRate: 30
};

// 设置录制文件路径
let filePath = 'path/to/save/recording.mp4';
let file = await fileIO.open(filePath, fileIO.OpenMode.READ_WRITE | fileIO.OpenMode.CREATE);

// 准备录制
await avRecorder.prepare({
    profile: avProfile,
    url: filePath
});

// 开始录制
await avRecorder.start();

// 停止录制
await avRecorder.stop();

// 释放资源
await avRecorder.release();
await fileIO.close(file);

在HarmonyOS鸿蒙Next中,音视频录制功能可以通过Recorder类实现。以下是一个简单的示例代码,展示如何录制音频:

import ohos.media.recorder.Recorder;
import ohos.media.common.Source;
import ohos.media.common.Format;

public class AudioRecorderExample {
    private Recorder recorder;

    public void startRecording(String outputPath) {
        recorder = new Recorder();
        recorder.setAudioSource(Recorder.AudioSource.MIC);
        recorder.setOutputFormat(Recorder.OutputFormat.MPEG_4);
        recorder.setAudioEncoder(Recorder.AudioEncoder.AAC);
        recorder.setOutputFile(outputPath);

        try {
            recorder.prepare();
            recorder.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void stopRecording() {
        if (recorder != null) {
            recorder.stop();
            recorder.release();
            recorder = null;
        }
    }
}

这段代码初始化了一个Recorder对象,设置音频源为麦克风,输出格式为MPEG-4,音频编码为AAC,并指定输出文件路径。录制完成后,调用stop方法停止录制并释放资源。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!