@@ -14,38 +14,44 @@ const char* FFmpegException::getMessage() const noexcept {
1414 return message;
1515}
1616
17- std::vector<AmplitudeData> analyzeAudio (const char *filename, FFmpegException *errorPtr) {
17+ std::vector<AmplitudeData> analyzeAudio (const char *filename, double groupBySeconds, FFmpegException *errorPtr) {
1818 std::vector<AmplitudeData> amplitudeData;
19-
19+
20+ // Проверка корректности groupBySeconds
21+ if (groupBySeconds <= 0 ) {
22+ *errorPtr = FFmpegException (" groupBySeconds must be greater than 0" );
23+ return amplitudeData;
24+ }
25+
2026 // Allocate memory for the AVFormatContext
2127 AVFormatContext *formatContext = avformat_alloc_context ();
2228 if (!formatContext) {
2329 *errorPtr = FFmpegException (" Failed to allocate AVFormatContext" );
2430 return amplitudeData;
2531 }
26-
32+
2733 // Open the input file
2834 if (avformat_open_input (&formatContext, filename, nullptr , nullptr ) != 0 ) {
2935 avformat_free_context (formatContext);
3036 *errorPtr = FFmpegException (" Failed to open input file" );
3137 return amplitudeData;
3238 }
33-
39+
3440 // Find stream information
3541 if (avformat_find_stream_info (formatContext, nullptr ) < 0 ) {
3642 avformat_close_input (&formatContext);
3743 *errorPtr = FFmpegException (" Failed to find stream information" );
3844 return amplitudeData;
3945 }
40-
46+
4147 // Find the best audio stream
4248 int audioStreamIndex = av_find_best_stream (formatContext, AVMEDIA_TYPE_AUDIO, -1 , -1 , nullptr , 0 );
4349 if (audioStreamIndex < 0 ) {
4450 avformat_close_input (&formatContext);
4551 *errorPtr = FFmpegException (" Failed to find audio stream" );
4652 return amplitudeData;
4753 }
48-
54+
4955 // Get codec parameters and find the corresponding decoder
5056 AVCodecParameters *codecParameters = formatContext->streams [audioStreamIndex]->codecpar ;
5157 const AVCodec *codec = avcodec_find_decoder (codecParameters->codec_id );
@@ -54,52 +60,53 @@ std::vector<AmplitudeData> analyzeAudio(const char *filename, FFmpegException *e
5460 *errorPtr = FFmpegException (" Failed to find codec" );
5561 return amplitudeData;
5662 }
57-
63+
5864 // Allocate memory for the AVCodecContext
5965 AVCodecContext *codecContext = avcodec_alloc_context3 (codec);
6066 if (!codecContext) {
6167 avformat_close_input (&formatContext);
6268 *errorPtr = FFmpegException (" Failed to allocate AVCodecContext" );
6369 return amplitudeData;
6470 }
65-
71+
6672 // Set codec parameters
6773 if (avcodec_parameters_to_context (codecContext, codecParameters) < 0 ) {
6874 avformat_close_input (&formatContext);
6975 avcodec_free_context (&codecContext);
7076 *errorPtr = FFmpegException (" Failed to set codec parameters" );
7177 return amplitudeData;
7278 }
73-
79+
7480 // Open the codec
7581 if (avcodec_open2 (codecContext, codec, nullptr ) < 0 ) {
7682 avformat_close_input (&formatContext);
7783 avcodec_free_context (&codecContext);
7884 *errorPtr = FFmpegException (" Failed to open codec" );
7985 return amplitudeData;
8086 }
81-
87+
8288 // Allocate memory for AVPacket and AVFrame
8389 AVPacket packet;
8490 AVFrame *frame = av_frame_alloc ();
85-
91+
8692 // Initialize variables for audio analysis
8793 int sampleRate = codecContext->sample_rate ;
8894 double accumulatedAmplitude = 0.0 ;
8995 long sampleCount = 0 ;
90-
96+ double currentTimeGroup = 0.0 ;
97+
9198 // Read frames from the input file
9299 while (av_read_frame (formatContext, &packet) >= 0 ) {
93100 if (packet.stream_index == audioStreamIndex) {
94101 // Send the packet to the codec
95102 if (avcodec_send_packet (codecContext, &packet) < 0 ) {
96103 break ;
97104 }
98-
105+
99106 // Receive frames from the codec
100107 while (avcodec_receive_frame (codecContext, frame) >= 0 ) {
101108 double timestampInSeconds = frame->pts * av_q2d (formatContext->streams [audioStreamIndex]->time_base );
102-
109+
103110 // Calculate amplitude for each sample in the frame
104111 for (int i = 0 ; i < frame->nb_samples ; i++) {
105112 for (int ch = 0 ; ch < codecContext->ch_layout .nb_channels ; ch++) {
@@ -108,36 +115,37 @@ std::vector<AmplitudeData> analyzeAudio(const char *filename, FFmpegException *e
108115 if (i < frame->linesize [ch]) {
109116 accumulatedAmplitude += frame->data [ch][i];
110117 sampleCount++;
111-
112- // Calculate amplitude per second and store the data
113- if (sampleCount >= sampleRate ) {
114- double amplitudePerSecond = accumulatedAmplitude / sampleRate ;
115-
118+
119+ // Calculate amplitude for the specified groupBySeconds
120+ if ((timestampInSeconds - currentTimeGroup) >= groupBySeconds ) {
121+ double amplitudePerGroup = accumulatedAmplitude / sampleCount ;
122+
116123 AmplitudeData data{};
117- data.timeInSeconds = timestampInSeconds ;
118- data.amplitude = amplitudePerSecond ;
119-
124+ data.timeInSeconds = currentTimeGroup ;
125+ data.amplitude = amplitudePerGroup ;
126+
120127 amplitudeData.push_back (data);
121-
128+
122129 accumulatedAmplitude = 0.0 ;
123130 sampleCount = 0 ;
131+ currentTimeGroup += groupBySeconds;
124132 }
125133 }
126134 }
127135 }
128136 }
129137 }
130138 }
131-
139+
132140 // Release the packet
133141 av_packet_unref (&packet);
134142 }
135-
143+
136144 // Clean up resources
137145 avformat_close_input (&formatContext);
138146 avcodec_free_context (&codecContext);
139147 av_frame_free (&frame);
140-
148+
141149 return amplitudeData;
142150}
143151}
0 commit comments