-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathextract_audio.c
More file actions
113 lines (94 loc) · 3.06 KB
/
extract_audio.c
File metadata and controls
113 lines (94 loc) · 3.06 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
/*
* copyright (c) 2024 Jack Lau
*
* This file is a tutorial about extrating audio stream from a container into a new container through ffmpeg API
*
* FFmpeg version 5.0.3
* Tested on Ubuntu 22.04, compiled with GCC 11.4.0
*/
#include <libavformat/avformat.h>
#include <libavutil/avutil.h>
int main(int argc, char *argv[])
{
int ret = -1;
int idx = -1;
//deal with arguments
char *src;
char *dst;
AVFormatContext *pFmtCtx = NULL;
AVFormatContext *oFmtCtx = NULL;
const AVOutputFormat *outFmt = NULL;
AVStream *inStream = NULL;
AVStream *outStream = NULL;
AVPacket pkt;
av_log_set_level(AV_LOG_DEBUG);
if(argc < 3){
av_log(NULL, AV_LOG_ERROR, "the arguments must be more than 3!\n");
}
src = argv[1];
dst = argv[2];
//open the multimedia file
if( (ret = avformat_open_input(&pFmtCtx, src, NULL, NULL)) < 0 ){
av_log(NULL, AV_LOG_ERROR, " %s \n", av_err2str(ret));
exit(-1);
}
//find the audio stream from container
if((idx = av_find_best_stream(pFmtCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0)) < 0){
av_log(pFmtCtx, AV_LOG_ERROR, "There is no audio stream!\n");
goto end;
}
//open the context of destination file
if((oFmtCtx = avformat_alloc_context()) < 0){
av_log(NULL, AV_LOG_ERROR, "No Memory!\n");
goto end;
}
outFmt = av_guess_format(NULL, dst, NULL);
oFmtCtx->oformat = outFmt;
//create a audio stream
outStream = avformat_new_stream(oFmtCtx, NULL);
//set the arguments of output Stream
inStream = pFmtCtx->streams[idx];
avcodec_parameters_copy(outStream->codecpar, inStream->codecpar);
outStream->codecpar->codec_tag = 0;
//binding
ret = avio_open2(&oFmtCtx->pb, dst, AVIO_FLAG_WRITE, NULL, NULL);
if(ret < 0){
av_log(oFmtCtx, AV_LOG_ERROR, "%s", av_err2str(ret));
goto end;
}
//write the head file of multimedia to destination file
ret = avformat_write_header(oFmtCtx, NULL);
if(ret < 0){
av_log(oFmtCtx, AV_LOG_ERROR, "%s", av_err2str(ret));
goto end;
}
//read audio data from multimedia files to write into destination file
while(av_read_frame(pFmtCtx, &pkt) >= 0){
if(pkt.stream_index == idx ){
pkt.pts = av_rescale_q_rnd(pkt.pts, inStream->time_base, outStream->time_base, (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
//the dts data is same as the the pts if the file is audio
pkt.dts = pkt.pts;
pkt.duration = av_rescale_q(pkt.duration, inStream->time_base, outStream->time_base);
pkt.stream_index = 0;
pkt.pos = -1;
av_interleaved_write_frame(oFmtCtx, &pkt);
av_packet_unref(&pkt);
}
}
//write end of file
av_write_trailer(oFmtCtx);
//free memory
end:
if(pFmtCtx){
avformat_close_input(&pFmtCtx);
pFmtCtx = NULL;
}
if(oFmtCtx->pb){
avio_close(oFmtCtx->pb);
}
if(oFmtCtx){
avformat_close_input(&oFmtCtx);
oFmtCtx = NULL;
}
return 0;
}