Shaka Packager SDK
Loading...
Searching...
No Matches
webvtt_file_buffer.cc
1// Copyright 2018 Google LLC All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file or at
5// https://developers.google.com/open-source/licenses/bsd
6
7#include <packager/media/formats/webvtt/webvtt_file_buffer.h>
8
9#include <cstddef>
10#include <cstdint>
11#include <string>
12
13#include <absl/log/check.h>
14#include <absl/strings/str_format.h>
15
16#include <packager/file.h>
17#include <packager/media/base/text_sample.h>
18#include <packager/media/formats/webvtt/webvtt_utils.h>
19
20namespace shaka {
21namespace media {
22namespace {
23const char* kHeader = "WEBVTT\n";
24const int kTsTimescale = 90000;
25} // namespace
26
27WebVttFileBuffer::WebVttFileBuffer(int32_t transport_stream_timestamp_offset_ms,
28 const std::string& style_region_config)
29 : transport_stream_timestamp_offset_(transport_stream_timestamp_offset_ms *
30 kTsTimescale / 1000),
31 style_region_config_(style_region_config) {
32 // Make sure we start with the same state that we would end up with if
33 // the caller reset our state.
34 Reset();
35}
36
37void WebVttFileBuffer::Reset() {
38 sample_count_ = 0;
39
40 buffer_.clear();
41 buffer_.append(kHeader);
42 if (transport_stream_timestamp_offset_ > 0) {
43 // https://tools.ietf.org/html/rfc8216#section-3.5 WebVTT.
44 absl::StrAppendFormat(&buffer_,
45 "X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:%d\n",
46 transport_stream_timestamp_offset_);
47 }
48 buffer_.append("\n"); // end of header.
49 if (!style_region_config_.empty()) {
50 buffer_.append(style_region_config_);
51 buffer_.append("\n\n");
52 }
53}
54
55void WebVttFileBuffer::Append(const TextSample& sample) {
56 DCHECK_GT(buffer_.size(), 0u) << "The buffer should at least have a header";
57
58 sample_count_++;
59
60 // Ids are optional
61 if (sample.id().length()) {
62 buffer_.append(sample.id());
63 buffer_.append("\n"); // end of id
64 }
65
66 // Write the times that the sample elapses.
67 buffer_.append(MsToWebVttTimestamp(sample.start_time()));
68 buffer_.append(" --> ");
69 buffer_.append(MsToWebVttTimestamp(sample.EndTime()));
70 const std::string settings = WebVttSettingsToString(sample.settings());
71 if (!settings.empty()) {
72 buffer_.append(" ");
73 buffer_.append(settings);
74 }
75 buffer_.append("\n"); // end of time & settings
76
77 buffer_.append(WebVttFragmentToString(sample.body()));
78 buffer_.append("\n"); // end of payload
79 buffer_.append("\n"); // end of sample
80}
81
82bool WebVttFileBuffer::WriteTo(File* file, uint64_t* size) {
83 DCHECK(file);
84 DCHECK_GT(buffer_.size(), 0u) << "The buffer should at least have a header";
85
86 if (size)
87 *size = buffer_.size();
88 const int written = file->Write(buffer_.c_str(), buffer_.size());
89 if (written < 0) {
90 return false;
91 }
92
93 return static_cast<size_t>(written) == buffer_.size();
94}
95} // namespace media
96} // namespace shaka
All the methods that are virtual are virtual for mocking.