7#include <packager/media/base/text_muxer.h>
13#include <absl/log/check.h>
15#include <packager/macros/compiler.h>
16#include <packager/macros/status.h>
17#include <packager/media/base/media_handler.h>
18#include <packager/media/base/muxer.h>
19#include <packager/media/base/muxer_options.h>
20#include <packager/media/base/muxer_util.h>
21#include <packager/media/base/stream_info.h>
22#include <packager/media/base/text_sample.h>
23#include <packager/media/base/text_stream_info.h>
24#include <packager/media/event/muxer_listener.h>
25#include <packager/status.h>
30TextMuxer::TextMuxer(
const MuxerOptions& options) : Muxer(options) {}
31TextMuxer::~TextMuxer() {}
33Status TextMuxer::InitializeMuxer() {
34 if (streams().size() != 1 || streams()[0]->stream_type() != kStreamText) {
35 return Status(error::MUXER_FAILURE,
36 "Incorrect streams given to WebVTT muxer");
39 auto copy = streams()[0]->Clone();
40 RETURN_IF_ERROR(InitializeStream(
static_cast<TextStreamInfo*
>(copy.get())));
42 muxer_listener()->OnMediaStart(options(), *copy, copy->time_scale(),
43 MuxerListener::kContainerText);
49Status TextMuxer::Finalize() {
50 const float duration_ms =
static_cast<float>(total_duration_ms_);
51 float duration_seconds = duration_ms / 1000;
55 MuxerListener::MediaRanges ranges;
56 if (duration_seconds == 0 && last_cue_ms_ != 0) {
57 DCHECK(options().segment_template.empty());
58 duration_seconds =
static_cast<float>(last_cue_ms_) / 1000;
61 RETURN_IF_ERROR(WriteToFile(options().output_file_name, &size));
63 ranges.subsegment_ranges.emplace_back();
66 const uint32_t kArbitrarySegmentNumber = 0;
68 muxer_listener()->OnNewSegment(
69 options().output_file_name, 0,
70 duration_seconds * streams()[0]->time_scale(), size,
71 kArbitrarySegmentNumber);
74 muxer_listener()->OnMediaEnd(ranges, duration_seconds);
79Status TextMuxer::AddTextSample(
size_t stream_id,
const TextSample& sample) {
83 if (sample.body().is_empty()) {
87 RETURN_IF_ERROR(AddTextSampleInternal(sample));
89 last_cue_ms_ = sample.EndTime();
93Status TextMuxer::FinalizeSegment(
size_t stream_id,
94 const SegmentInfo& segment_info) {
97 total_duration_ms_ += segment_info.duration;
99 const std::string& segment_template = options().segment_template;
100 DCHECK(!segment_template.empty());
102 const int64_t start = segment_info.start_timestamp;
103 const int64_t duration = segment_info.duration;
104 const uint32_t segment_number = segment_info.segment_number;
106 const uint32_t bandwidth = options().bandwidth;
108 const std::string filename =
109 GetSegmentName(segment_template, start, segment_number, bandwidth);
111 RETURN_IF_ERROR(WriteToFile(filename, &size));
113 muxer_listener()->OnNewSegment(filename, start, duration, size,
All the methods that are virtual are virtual for mocking.