7 #include "packager/media/base/muxer.h"
11 #include "packager/media/base/media_sample.h"
12 #include "packager/media/base/muxer_util.h"
13 #include "packager/status_macros.h"
18 const bool kInitialEncryptionInfo =
true;
19 const int64_t kStartTime = 0;
22 Muxer::Muxer(
const MuxerOptions& options) : options_(options) {
25 if (options_.output_file_name.find(
"$") != std::string::npos)
26 output_file_template_ = options_.output_file_name;
36 muxer_listener_ = std::move(muxer_listener);
40 std::unique_ptr<ProgressListener> progress_listener) {
41 progress_listener_ = std::move(progress_listener);
46 switch (stream_data->stream_data_type) {
47 case StreamDataType::kStreamInfo:
48 streams_.push_back(std::move(stream_data->stream_info));
49 return ReinitializeMuxer(kStartTime);
50 case StreamDataType::kSegmentInfo: {
51 const auto& segment_info = *stream_data->segment_info;
52 if (muxer_listener_ && segment_info.is_encrypted) {
54 segment_info.key_rotation_encryption_config.get();
56 if (encryption_config && encryption_config->key_id != current_key_id_) {
57 muxer_listener_->OnEncryptionInfoReady(
58 !kInitialEncryptionInfo, encryption_config->protection_scheme,
59 encryption_config->key_id, encryption_config->constant_iv,
60 encryption_config->key_system_info);
61 current_key_id_ = encryption_config->key_id;
63 if (!encryption_started_) {
64 encryption_started_ =
true;
65 muxer_listener_->OnEncryptionStart();
68 return FinalizeSegment(stream_data->stream_index, segment_info);
70 case StreamDataType::kMediaSample:
71 return AddMediaSample(stream_data->stream_index,
72 *stream_data->media_sample);
73 case StreamDataType::kTextSample:
74 return AddTextSample(stream_data->stream_index,
75 *stream_data->text_sample);
76 case StreamDataType::kCueEvent:
77 if (muxer_listener_) {
78 const int64_t time_scale =
79 streams_[stream_data->stream_index]->time_scale();
80 const double time_in_seconds = stream_data->cue_event->time_in_seconds;
81 const int64_t scaled_time =
82 static_cast<int64_t
>(time_in_seconds * time_scale);
83 muxer_listener_->OnCueEvent(scaled_time,
84 stream_data->cue_event->cue_data);
87 if (!output_file_template_.empty()) {
88 RETURN_IF_ERROR(Finalize());
89 RETURN_IF_ERROR(ReinitializeMuxer(scaled_time));
94 VLOG(3) <<
"Stream data type "
95 <<
static_cast<int>(stream_data->stream_data_type) <<
" ignored.";
110 Status Muxer::AddTextSample(
size_t stream_id,
const TextSample& sample) {
114 Status Muxer::ReinitializeMuxer(int64_t timestamp) {
115 if (muxer_listener_ && streams_.back()->is_encrypted()) {
116 const EncryptionConfig& encryption_config =
117 streams_.back()->encryption_config();
118 muxer_listener_->OnEncryptionInfoReady(
119 kInitialEncryptionInfo, encryption_config.protection_scheme,
120 encryption_config.key_id, encryption_config.constant_iv,
121 encryption_config.key_system_info);
122 current_key_id_ = encryption_config.key_id;
124 if (!output_file_template_.empty()) {
128 GetSegmentName(output_file_template_, timestamp, output_file_index_++,
131 return InitializeMuxer();