Program Listing for File transcript_result.hpp#
↰ Return to documentation for file (src/analysis/transcript_result.hpp)
#pragma once
#include <QString>
#include <QVector>
#include <cstdint>
namespace mosaic {
/// One transcribed segment. Mirrors run_diarize.py's assign_speakers() output
/// schema exactly (see analysis/diarize/pipeline.py).
struct TranscriptSegment {
int64_t startMs = 0;
int64_t endMs = 0;
QString speaker; ///< Empty = no diarization turn overlapped, or diarization wasn't run.
QString text;
};
/// Parses a "<name>.transcript.json" file written by analysis/run_diarize.py
/// into a queryable in-memory structure, for the Analysis tab's Speaker
/// Diarization plugin (transcript table + playback-synced highlighting).
///
/// Usage:
/// @code
/// auto result = TranscriptResult::load(jsonPath);
/// if (result.is_valid()) { ... }
/// @endcode
class TranscriptResult {
public:
TranscriptResult() = default;
/// Parses jsonPath. Returns a default-constructed (is_valid() == false)
/// result if the file is missing or malformed.
static TranscriptResult load(const QString& jsonPath);
[[nodiscard]] bool is_valid() const { return valid_; }
[[nodiscard]] bool has_diarization() const { return hasDiarization_; }
[[nodiscard]] const QString& source_audio() const { return sourceAudio_; }
[[nodiscard]] const QString& language() const { return language_; }
[[nodiscard]] const QVector<TranscriptSegment>& segments() const { return segments_; }
/// Binary search by start time (segments() is chronological, matching
/// run_diarize.py's write order). Returns nullptr if ms falls in a gap
/// between segments, before the first, or after the last one ends.
[[nodiscard]] const TranscriptSegment* segment_at(int64_t ms) const;
private:
bool valid_ = false;
bool hasDiarization_ = false;
QString sourceAudio_;
QString language_;
QVector<TranscriptSegment> segments_;
};
} // namespace mosaic