Open an audio file for reading.
131{
133
139 }
140
144
145 auto ctx = std::make_shared<FFmpegContext>();
146 if (avformat_open_input(&ctx->format_context, filepath.c_str(), nullptr, nullptr) < 0) {
147 set_error(
"Failed to open file: " + filepath);
148 return false;
149 }
150
151 if (avformat_find_stream_info(ctx->format_context, nullptr) < 0) {
153 return false;
154 }
155
156 const AVCodec* codec = nullptr;
157 ctx->audio_stream_index = av_find_best_stream(
158 ctx->format_context, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
159
160 if (ctx->audio_stream_index < 0 || !codec) {
162 return false;
163 }
164
165 ctx->codec_context = avcodec_alloc_context3(codec);
166 if (!ctx->codec_context) {
167 set_error(
"Failed to allocate codec context");
168 return false;
169 }
170
171 AVStream* stream = ctx->format_context->streams[ctx->audio_stream_index];
172 if (avcodec_parameters_to_context(ctx->codec_context, stream->codecpar) < 0) {
173 set_error(
"Failed to copy codec parameters");
174 return false;
175 }
176
177 if (avcodec_open2(ctx->codec_context, codec, nullptr) < 0) {
179 return false;
180 }
181
182 if (stream->duration != AV_NOPTS_VALUE && stream->time_base.num && stream->time_base.den) {
183 double duration_seconds = stream->duration * av_q2d(stream->time_base);
184 ctx->total_frames = static_cast<uint64_t>(duration_seconds * ctx->codec_context->sample_rate);
185 } else if (ctx->format_context->duration != AV_NOPTS_VALUE) {
186 double duration_seconds = ctx->format_context->duration / static_cast<double>(AV_TIME_BASE);
187 ctx->total_frames = static_cast<uint64_t>(duration_seconds * ctx->codec_context->sample_rate);
188 } else {
189 ctx->total_frames = 0;
190 }
191
192 ctx->sample_rate = ctx->codec_context->sample_rate;
193 ctx->channels = ctx->codec_context->ch_layout.nb_channels;
196 return false;
197 }
198
199 if (!ctx->is_valid()) {
200 set_error(
"Invalid context after initialization");
201 return false;
202 }
203
206 }
207
210 }
211
214 return true;
215}
std::shared_mutex m_context_mutex
void extract_regions(const std::shared_ptr< FFmpegContext > &ctx)
Extract region information from the file.
void set_error(const std::string &error) const
Set the last error message.
std::atomic< uint64_t > m_current_frame_position
Current frame position for reading.
void extract_metadata(const std::shared_ptr< FFmpegContext > &ctx)
Extract metadata from the file.
bool setup_resampler(const std::shared_ptr< FFmpegContext > &ctx)
Set up the FFmpeg resampler if needed.
std::shared_ptr< FFmpegContext > m_context
std::optional< FileMetadata > m_cached_metadata
Cached file metadata.
std::vector< FileRegion > m_cached_regions
Cached file regions (markers, loops, etc.).
void clear_error() const
Clear the last error message.
std::string m_filepath
Path to the currently open file.
FileReadOptions m_options
File read options used for this session.
@ EXTRACT_METADATA
Extract file metadata.
@ EXTRACT_REGIONS
Extract semantic regions (format-specific)
@ NONE
No special options.