AudioFile_PlayDeal.c
6.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include "libavutil/opt.h"
#include "libavutil/channel_layout.h"
#include "libavutil/samplefmt.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
#include "libavfilter/buffersink.h"
#include "libavfilter/buffersrc.h"
#include "libavcodec/avcodec.h"
#include <stdio.h>
#include "JZsdkLib.h"
#include "Megaphone/Megaphone.h"
#include "AudioDeal/AudioDeal.h"
#include "./AudioFile_PlayDeal.h"
#include "AudioDeal/FF_Statement.h"
//音频文件直接播放
T_JZsdkReturnCode AudioFile_StartPlay_Interface(unsigned char* FilePath)
{
T_JZsdkReturnCode jzret;
//1、检测这个文件是否存在
jzret = JZsdk_check_file_exists((const char *)FilePath);
if (jzret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
{
JZSDK_LOG_INFO("播放文件不存在");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//2、创建音频解码器
const AVCodec *codec;
AVCodecContext *codec_ctx = NULL;
double total_duration = 0; // 累计播放时间(秒)
int last_printed_second = -1; // 上次打印的秒数,初始化为-1表示还没有打印过
//3、创建一个音频上下文
AVFormatContext *fmt_ctx = avformat_alloc_context();
if (!fmt_ctx) {
JZSDK_LOG_ERROR("无法分配AVFormatContext");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//4、打开输出的音频文件
int ret = avformat_open_input(&fmt_ctx, FilePath, NULL, NULL);
if (ret < 0) {
JZSDK_LOG_ERROR("歌曲播放文件打开失败");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//5、检索音频的流信息
if (avformat_find_stream_info(fmt_ctx, NULL) < 0)
{
JZSDK_LOG_ERROR("检索音频的流信息失败");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//6、找到音频流信息
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
if (ret < 0) {
JZSDK_LOG_ERROR("无法从文件中找到音频流信息 %d",ret);
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
int audio_stream_index = ret;
// //7、查找解码器
// codec = avcodec_find_decoder(fmt_ctx->streams[audio_stream_index]->codecpar->codec_id);
// if (!codec)
// {
// JZSDK_LOG_ERROR("无法找到解码器");
// return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
// }
//8、分配解码器上下文
codec_ctx = avcodec_alloc_context3(codec);
if (!codec_ctx) {
JZSDK_LOG_ERROR("Could not allocate audio codec context");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
if (avcodec_parameters_to_context(codec_ctx, fmt_ctx->streams[audio_stream_index]->codecpar) < 0)
{
JZSDK_LOG_ERROR("Could not copy codec parameters to decoder context");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
codec_ctx->pkt_timebase = fmt_ctx->streams[audio_stream_index]->time_base;
//9、打开解码器
if (avcodec_open2(codec_ctx, codec, NULL) < 0) {
JZSDK_LOG_ERROR("Could not open codec");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//10、分配AVPacket和AVFrame
AVPacket *packet = av_packet_alloc();
AVFrame *frame = av_frame_alloc();
if (!packet || !frame)
{
JZSDK_LOG_ERROR("Could not allocate packet or frame");
return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
}
//如果此次输入的音频数据不同于采样的当前设置,重设采样
AudioDeal_ResampleRest(codec_ctx->sample_rate, codec_ctx->ch_layout, codec_ctx->sample_fmt);
printf("开始读取内容\n");
int Last_duration = 0;
//读取,并解码歌曲数据
while (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_ON)
{
//读取音频内容
if (av_read_frame(fmt_ctx, packet) < 0) //没有正常取出数据包
{
//执行读取数据完毕之类的操作
JZSDK_LOG_ERROR("没有正常取出数据包");
break;
}
//如果音频流指引值不相同
if (packet->stream_index != audio_stream_index)
{
av_packet_unref(packet);
continue;
}
// 发送数据包到解码器
ret = avcodec_send_packet(codec_ctx, packet);
if (ret < 0)
{
char errbuf[128];
av_strerror(ret, errbuf, sizeof(errbuf));
JZSDK_LOG_ERROR("Error while sending a packet to the decoder %s",errbuf);
break;
}
while ((ret >= 0) && (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_ON))
{
ret = avcodec_receive_frame(codec_ctx, frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
{
//JZSDK_LOG_ERROR("解码完毕");
break;
}
else if (ret < 0)
{
JZSDK_LOG_ERROR("Error while receiving a frame from the decoder\n");
break;
}
// 计算当前帧的持续时间(秒)
double frame_duration = (double)frame->nb_samples / codec_ctx->sample_rate;
// 累计总持续时间
total_duration += frame_duration;
//JZSDK_LOG_INFO("当前播放时间%f",total_duration);
// 检查是否需要打印
int current_second = (int)floor(total_duration); // 获取当前总时间的整数秒部分
if (current_second > last_printed_second)
{
printf("nb:%d rate:%d duration:%f total_duration:%f\n", frame->nb_samples, codec_ctx->sample_rate, frame_duration, current_second);
last_printed_second = current_second; // 更新上次打印的秒数
}
AudioFile_Stream_DataInput(frame);
}
av_packet_unref(packet);
}
printf("歌曲数据处理完毕 total_duration %f\n",total_duration);
// 清理资源
av_frame_free(&frame);
av_packet_free(&packet);
avcodec_free_context(&codec_ctx);
avformat_close_input(&fmt_ctx);
return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}