Read the original article:How to download and play voice data in string format?
Requirement Description
How to properly play the generated voice string obtained from the server?
Background Knowledge
- Applications can initiate an HTTP data request using HttpRequest, supporting common methods such as GET, POST, OPTIONS, HEAD, PUT, DELETE, TRACE, and CONNECT.
- AVPlayer can transcode audio/video media resources (e.g., mp4, mp3, mkv, mpeg-ts, etc.) into renderable images and audible audio analog signals, and play them through output devices. AVPlayer provides a comprehensive and integrated playback capability; applications only need to provide the source of streaming media and do not need to handle data parsing or decoding to achieve playback.
Implementation Steps
1.Use the HttpRequest request method, passing the request URL and optional parameters, to initiate an HTTP data request. In the callback, parse the server response content based on actual business needs.
private async postHttp() {
let httpRequest = http.createHttp();
httpRequest.on('headersReceive', (header) => {
hilog.info(0x0000, 'testTag', '---httpRequestSucess%{public}s', header)
});
let avPlayer: media.AVPlayer = await media.createAVPlayer();
httpRequest.request(
this.url,
{
method: http.RequestMethod.POST,
header: {
'contentType': 'application/json'
},
extraData: 'data to send',
expectDataType: http.HttpDataType.STRING,
usingCache: true,
priority: 1,
connectTimeout: 60000,
readTimeout: 60000,
usingProtocol: http.HttpProtocol.HTTP1_1,
usingProxy: false
}, async (err: BusinessError, data: http.HttpResponse) => {
if (!err) {
let strr = data.result as string;
let lines = strr.split('\n');
this.musics = '';
for (let i = 0; i < lines.length; i++) {
if (lines[i] && lines[i] !== '' && lines[i].startsWith('data:')) {
let linei = lines[i].slice(5);
let dataEntry: DataEntry = JSON.parse(linei) as DataEntry;
let resultData: ResultData = dataEntry.data;
let music = resultData.audio;
if (music && music !== '') {
this.musics+= music;
}
}
}
let fileName = this.save(this.musics)
this.avPlayerDataSrcNoSeekDemo(avPlayer, fileName);
httpRequest.destroy();
} else {
httpRequest.off('headersReceive');
httpRequest.destroy();
}
}
);
}
2.Convert the string-formatted data received from the server into MP3 format and store it in the local app sandbox directory.
save(music: string) {
const arraybuffer = this.hexStringToArrayBuffer(music);
let fileName = `temp_audio_${Date.now()}.mp3`
const filePath = `${this.context?.filesDir}/${fileName}`;
const file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
try {
fs.writeSync(file.fd, arraybuffer);
}finally {
fs.closeSync(file);
}
return fileName;
}
hexStringToArrayBuffer(hex: string): ArrayBuffer {
const len = hex.length / 2;
const buffer = new ArrayBuffer(len);
const uint8Array = new Uint8Array(buffer);
for (let i = 0; i < len; i++) {
uint8Array[i] = parseInt(hex.substr(i * 2, 2), 16)
}
return buffer;
}
3.Use AVPlayer to play MP3 audio files stored in the local app sandbox directory.
async avPlayerDataSrcNoSeekDemo(avPlayer: media.AVPlayer, fileName: string) {
this.setAVPlayerCallback(avPlayer);
let src: media.AVDataSrcDescriptor = {
fileSize: -1,
callback: (buf: ArrayBuffer, length: number) => {
let num = 0;
if (buf === undefined || length === undefined) {
return -1;
}
num = fs.readSync(this.fd, buf);
if (num > 0) {
return num;
}
return -1;
}
};
if (this.context !== undefined) {
let pathDir = this.context.filesDir;
let path = pathDir + `/${fileName}`;
let file = fs.openSync(path)
this.fd = file.fd;
avPlayer.dataSrc = src;
}
}
4.The complete demo is as follows.
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileIo as fs } from '@kit.CoreFileKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { audio } from '@kit.AudioKit';
import { media } from '@kit.MediaKit';
@Entry
@Component
export struct Player {
// Online link, returns the hexadecimal data stream of the audio.
private url: string = 'www.example.com';
private context:Context|undefined = this.getUIContext().getHostContext()
@State musics: string = '';
fd: number = 0;
build() {
Column() {
Button(`Download and Play`).onClick(() => {
this.postHttp();
})
}.width('100%')
}
private async postHttp() {
let httpRequest = http.createHttp();
httpRequest.on('headersReceive', (header) => {
hilog.info(0x0000, 'testTag', '---httpRequestSucess%{public}s', header)
});
let avPlayer: media.AVPlayer = await media.createAVPlayer();
httpRequest.request(
this.url,
{
method: http.RequestMethod.POST,
header: {
'contentType': 'application/json'
},
extraData: 'data to send',
expectDataType: http.HttpDataType.STRING,
usingCache: true,
priority: 1,
connectTimeout: 60000,
readTimeout: 60000,
usingProtocol: http.HttpProtocol.HTTP1_1,
usingProxy: false
}, async (err: BusinessError, data: http.HttpResponse) => {
if (!err) {
let strr = data.result as string;
let lines = strr.split('\n');
this.musics = '';
for (let i = 0; i < lines.length; i++) {
if (lines[i] && lines[i] !== '' && lines[i].startsWith('data:')) {
let linei = lines[i].slice(5);
let dataEntry: DataEntry = JSON.parse(linei) as DataEntry;
let resultData: ResultData = dataEntry.data;
let music = resultData.audio;
if (music && music !== '') {
this.musics+= music;
}
}
}
let fileName = this.save(this.musics)
this.avPlayerDataSrcNoSeekDemo(avPlayer, fileName);
httpRequest.destroy();
} else {
httpRequest.off('headersReceive');
httpRequest.destroy();
}
}
);
}
save(music: string) {
const arraybuffer = this.hexStringToArrayBuffer(music);
let fileName = `temp_audio_${Date.now()}.mp3`
const filePath = `${this.context?.filesDir}/${fileName}`;
const file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
try {
fs.writeSync(file.fd, arraybuffer);
}finally {
fs.closeSync(file);
}
return fileName;
}
hexStringToArrayBuffer(hex: string): ArrayBuffer {
const len = hex.length / 2;
const buffer = new ArrayBuffer(len);
const uint8Array = new Uint8Array(buffer);
for (let i = 0; i < len; i++) {
uint8Array[i] = parseInt(hex.substr(i * 2, 2), 16)
}
return buffer;
}
async avPlayerDataSrcNoSeekDemo(avPlayer: media.AVPlayer, fileName: string) {
this.setAVPlayerCallback(avPlayer);
let src: media.AVDataSrcDescriptor = {
fileSize: -1,
callback: (buf: ArrayBuffer, length: number) => {
let num = 0;
if (buf === undefined || length === undefined) {
return -1;
}
num = fs.readSync(this.fd, buf);
if (num > 0) {
return num;
}
return -1;
}
};
if (this.context !== undefined) {
let pathDir = this.context.filesDir;
let path = pathDir + `/${fileName}`;
let file = fs.openSync(path)
this.fd = file.fd;
avPlayer.dataSrc = src;
}
}
setAVPlayerCallback(avPlayer: media.AVPlayer) {
avPlayer.on('seekDone', (seekDoneTime: number) => {
console.info(`AVPlayer seek succeeded, seek time is ${seekDoneTime}`);
});
avPlayer.on('error', (err: BusinessError) => {
console.error(`Invoke avPlayer failed, code is ${err.code}, message is ${err.message}`);
avPlayer.reset();
});
avPlayer.on('stateChange', async (state: string, reason: media.StateChangeReason) => {
switch (state) {
case 'idle':
console.info('AVPlayer state idle called.');
break;
case 'initialized':
console.info('AVPlayer state initialized called.');
avPlayer.audioRendererInfo = {
usage: audio.StreamUsage.STREAM_USAGE_MUSIC,
rendererFlags: 0
};
avPlayer.prepare();
break;
case 'prepared':
console.info('AVPlayer state prepared called.');
avPlayer.play();
break;
case 'completed':
console.info('AVPlayer state completed called.');
avPlayer.stop();
break;
case 'stopped':
console.info('AVPlayer state stopped called.');
avPlayer.reset();
break;
case 'released':
console.info('AVPlayer state released called.');
break;
default:
console.info('AVPlayer state unknown called.');
break;
}
});
}
}
class DataEntry {
data: ResultData = new ResultData;
}
class ResultData {
audio: string = '';
}
Code Running Effect Image
The file exists in the sandbox directory and plays normally.
Code Check
Restrictions and Limitations
- This example supports API Version 20 Release and above.
- This example supports HarmonyOS SDK Version 6.0.0 Release and above.
- This example requires DevEco Studio Version 6.0.0 Release and above to compile and run.


Top comments (0)