88#include " audio_grabber.h"
99
1010AudioGrabber::AudioGrabber (std::string filename): filename(filename) {
11- // Has been removed
12- // v_register_all(); //maybe move
1311 // Open video file
1412 if (avformat_open_input (&formatContext, filename.c_str (), nullptr , nullptr ) != 0 ) {
1513 throw std::runtime_error (" Failed to open video file!" );
@@ -20,12 +18,11 @@ AudioGrabber::AudioGrabber(std::string filename): filename(filename) {
2018 throw std::runtime_error (" Failed to find stream info!" );
2119 }
2220
23-
24- AVCodec *codec = nullptr ;
21+ const AVCodec *codec = nullptr ;
2522 for (unsigned int i = 0 ; i < formatContext->nb_streams ; i++) {
2623 if (formatContext->streams [i]->codecpar ->codec_type == AVMEDIA_TYPE_AUDIO) {
2724 audioStreamIndex = i;
28- codec = const_cast <AVCodec*>( avcodec_find_decoder (formatContext->streams [i]->codecpar ->codec_id ) );
25+ codec = avcodec_find_decoder (formatContext->streams [i]->codecpar ->codec_id );
2926 break ;
3027 }
3128 }
@@ -36,46 +33,57 @@ AudioGrabber::AudioGrabber(std::string filename): filename(filename) {
3633 throw std::runtime_error (" Audio stream not found!" );
3734 }
3835
39-
4036 codecContext = avcodec_alloc_context3 (codec);
4137 avcodec_parameters_to_context (codecContext, formatContext->streams [audioStreamIndex]->codecpar );
4238 avcodec_open2 (codecContext, codec, nullptr );
4339
4440 swrContext = swr_alloc ();
45- av_opt_set_int (swrContext, " in_channel_layout" , codecContext->channel_layout , 0 );
41+
42+ // FFmpeg 7: use AVChannelLayout instead of channel_layout
43+ av_opt_set_chlayout (swrContext, " in_chlayout" , &codecContext->ch_layout , 0 );
4644 av_opt_set_int (swrContext, " in_sample_rate" , codecContext->sample_rate , 0 );
4745 av_opt_set_sample_fmt (swrContext, " in_sample_fmt" , codecContext->sample_fmt , 0 );
4846
49- av_opt_set_int (swrContext, " out_channel_layout" , AV_CH_LAYOUT_MONO, 0 ); // Mono output
50- av_opt_set_int (swrContext, " out_sample_rate" , 16000 , 0 ); // 16kHz output sample rate
51- av_opt_set_sample_fmt (swrContext, " out_sample_fmt" , AV_SAMPLE_FMT_S16, 0 ); // 16-bit PCM output
47+ AVChannelLayout out_ch_layout;
48+ av_channel_layout_default (&out_ch_layout, 1 ); // mono
49+ av_opt_set_chlayout (swrContext, " out_chlayout" , &out_ch_layout, 0 );
50+ av_opt_set_int (swrContext, " out_sample_rate" , 16000 , 0 ); // 16kHz output
51+ av_opt_set_sample_fmt (swrContext, " out_sample_fmt" , AV_SAMPLE_FMT_S16, 0 ); // 16-bit PCM
5252
5353 if (swr_init (swrContext) < 0 ) {
5454 throw std::runtime_error (" Failed to initialize resampler!" );
5555 }
5656}
5757
5858AudioGrabber::~AudioGrabber () {
59- avcodec_close (codecContext);
60- avformat_close_input (&formatContext);
61- swr_free (&swrContext);
59+ if (codecContext) {
60+ avcodec_free_context (&codecContext); // FFmpeg 7 replacement for avcodec_close
61+ }
62+ if (formatContext) {
63+ avformat_close_input (&formatContext);
64+ }
65+ if (swrContext) {
66+ swr_free (&swrContext);
67+ }
6268}
6369
6470std::vector<float > AudioGrabber::grab_chunk (uint64_t start_time, uint64_t duration) {
6571 AVFrame *frame = av_frame_alloc ();
6672 AVPacket packet;
67- std::vector<float > resampledAudio; // For storing resampled audio data as float
68- // Seek to the starting time (start_time in seconds)
69- int64_t startPts = av_rescale_q (start_time * AV_TIME_BASE, AV_TIME_BASE_Q, formatContext->streams [audioStreamIndex]->time_base );
73+ std::vector<float > resampledAudio;
74+
75+ int64_t startPts = av_rescale_q (start_time * AV_TIME_BASE, AV_TIME_BASE_Q,
76+ formatContext->streams [audioStreamIndex]->time_base );
7077 av_seek_frame (formatContext, audioStreamIndex, startPts, AVSEEK_FLAG_BACKWARD);
7178
72- int audioDurationPts = av_rescale_q (duration * AV_TIME_BASE, AV_TIME_BASE_Q, formatContext->streams [audioStreamIndex]->time_base );
79+ int audioDurationPts = av_rescale_q (duration * AV_TIME_BASE, AV_TIME_BASE_Q,
80+ formatContext->streams [audioStreamIndex]->time_base );
81+
7382 int decoded = 0 ;
7483 while (av_read_frame (formatContext, &packet) >= 0 && decoded < audioDurationPts) {
7584 if (packet.stream_index == audioStreamIndex) {
7685 if (avcodec_send_packet (codecContext, &packet) >= 0 ) {
7786 while (avcodec_receive_frame (codecContext, frame) >= 0 ) {
78- // Resample the audio to 16kHz
7987 int outSamples = swr_get_out_samples (swrContext, frame->nb_samples );
8088 std::vector<uint8_t > buffer (outSamples * av_get_bytes_per_sample (AV_SAMPLE_FMT_S16));
8189 uint8_t *outBuffer[] = { buffer.data () };
@@ -85,9 +93,8 @@ std::vector<float> AudioGrabber::grab_chunk(uint64_t start_time, uint64_t durati
8593
8694 int16_t *resampledData = reinterpret_cast <int16_t *>(buffer.data ());
8795
88- // Convert resampled int16_t samples to float and store in resampledAudio
8996 for (int i = 0 ; i < resampledSamples; i++) {
90- float sample = resampledData[i] / 32768 .0f ; // Convert to float in range [-1.0, 1.0]
97+ float sample = resampledData[i] / 32768 .0f ;
9198 resampledAudio.push_back (sample);
9299 }
93100 }
@@ -96,6 +103,7 @@ std::vector<float> AudioGrabber::grab_chunk(uint64_t start_time, uint64_t durati
96103 }
97104 av_packet_unref (&packet);
98105 }
106+
99107 av_frame_free (&frame);
100108 return resampledAudio;
101109}
0 commit comments