Resolve and cache the reader used for waveform extraction (prefer a detached FFmpegReader clone)
| 400 | |
| 401 | // Resolve and cache the reader used for waveform extraction (prefer a detached FFmpegReader clone) |
| 402 | ReaderBase* AudioWaveformer::ResolveWaveformReader() { |
| 403 | if (source_initialized) { |
| 404 | return resolved_reader ? resolved_reader : reader; |
| 405 | } |
| 406 | source_initialized = true; |
| 407 | |
| 408 | resolved_reader = ResolveSourceReader(reader); |
| 409 | |
| 410 | // Prefer a detached, audio-only FFmpegReader clone so we never mutate the live reader used for preview. |
| 411 | if (auto ff_reader = dynamic_cast<FFmpegReader*>(resolved_reader)) { |
| 412 | const Json::Value ff_json = ff_reader->JsonValue(); |
| 413 | const std::string path = ff_json.get("path", "").asString(); |
| 414 | if (!path.empty()) { |
| 415 | try { |
| 416 | auto clone = std::make_unique<FFmpegReader>(path, false); |
| 417 | clone->SetJsonValue(ff_json); |
| 418 | clone->info.has_video = false; // explicitly audio-only for waveform extraction |
| 419 | detached_reader = std::move(clone); |
| 420 | resolved_reader = detached_reader.get(); |
| 421 | } catch (...) { |
| 422 | // Fall back to using the original reader if cloning fails |
| 423 | detached_reader.reset(); |
| 424 | resolved_reader = ResolveSourceReader(reader); |
| 425 | } |
| 426 | } |
| 427 | } |
| 428 | |
| 429 | return resolved_reader ? resolved_reader : reader; |
| 430 | } |
nothing calls this directly
no test coverage detected