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