7 #include "packager/media/formats/webvtt/webvtt_output_handler.h" 9 #include "packager/base/logging.h" 10 #include "packager/file/file.h" 11 #include "packager/media/base/muxer_util.h" 12 #include "packager/media/formats/webvtt/webvtt_timestamp.h" 16 void WebVttOutputHandler::WriteCue(
const std::string&
id,
19 const std::string& settings,
20 const std::string& payload) {
23 const std::string start = MsToWebVttTimestamp(start_ms);
24 const std::string end = MsToWebVttTimestamp(end_ms);
32 buffer_.append(start);
33 buffer_.append(
" --> ");
37 if (settings.length()) {
39 buffer_.append(settings);
43 buffer_.append(payload);
48 Status WebVttOutputHandler::WriteSegmentToFile(
const std::string& filename) {
50 const std::string WEBVTT_HEADER =
"WEBVTT\n\n";
52 File* file =
File::Open(filename.c_str(),
"w");
54 if (file ==
nullptr) {
55 return Status(error::FILE_FAILURE,
"Failed to open " + filename);
59 written = file->Write(WEBVTT_HEADER.c_str(), WEBVTT_HEADER.size());
60 if (written != WEBVTT_HEADER.size()) {
61 return Status(error::FILE_FAILURE,
"Failed to write webvtt header to file");
64 written = file->Write(buffer_.c_str(), buffer_.size());
65 if (written != buffer_.size()) {
66 return Status(error::FILE_FAILURE,
67 "Failed to write webvtt cotnent to file");
74 bool closed = file->Close();
76 return Status(error::FILE_FAILURE,
"Failed to close " + filename);
82 Status WebVttOutputHandler::InitializeInternal() {
86 Status WebVttOutputHandler::Process(std::unique_ptr<StreamData> stream_data) {
87 switch (stream_data->stream_data_type) {
88 case StreamDataType::kStreamInfo:
89 return OnStreamInfo(*stream_data->stream_info);
90 case StreamDataType::kSegmentInfo:
91 return OnSegmentInfo(*stream_data->segment_info);
92 case StreamDataType::kTextSample:
93 return OnTextSample(*stream_data->text_sample);
95 return Status(error::INTERNAL_ERROR,
96 "Invalid stream data type for this handler");
100 Status WebVttOutputHandler::OnFlushRequest(
size_t input_stream_index) {
105 WebVttSegmentedOutputHandler::WebVttSegmentedOutputHandler(
106 const MuxerOptions& muxer_options,
107 std::unique_ptr<MuxerListener> muxer_listener)
108 : muxer_options_(muxer_options),
109 muxer_listener_(
std::move(muxer_listener)) {}
111 Status WebVttSegmentedOutputHandler::OnStreamInfo(
const StreamInfo& info) {
112 muxer_listener_->OnMediaStart(muxer_options_, info, info.time_scale(),
113 MuxerListener::kContainerText);
117 Status WebVttSegmentedOutputHandler::OnSegmentInfo(
const SegmentInfo& info) {
118 total_duration_ms_ += info.duration;
120 const std::string& segment_template = muxer_options_.segment_template;
121 const uint32_t index = segment_index_++;
122 const uint64_t start = info.start_timestamp;
123 const uint64_t duration = info.duration;
124 const uint32_t bandwidth = 0;
127 const std::string filename =
128 GetSegmentName(segment_template, start, index, bandwidth);
132 Status write_status = WriteSegmentToFile(filename);
133 if (!write_status.ok()) {
139 muxer_listener_->OnNewSegment(filename, start, duration, size);
144 Status WebVttSegmentedOutputHandler::OnTextSample(
const TextSample& sample) {
145 const std::string&
id = sample.id();
146 const uint64_t start_ms = sample.start_time();
147 const uint64_t end_ms = sample.EndTime();
148 const std::string& settings = sample.settings();
149 const std::string& payload = sample.payload();
151 WriteCue(
id, start_ms, end_ms, settings, payload);
155 Status WebVttSegmentedOutputHandler::OnStreamEnd() {
156 const float duration_ms =
static_cast<float>(total_duration_ms_);
157 const float duration_seconds = duration_ms / 1000.0f;
159 MuxerListener::MediaRanges empty_ranges;
160 muxer_listener_->OnMediaEnd(empty_ranges, duration_seconds);
All the methods that are virtual are virtual for mocking.
static int64_t GetFileSize(const char *file_name)
virtual bool Open()=0
Internal open. Should not be used directly.