17 #include <glog/logging.h> 42 std::string RandomUrl() {
43 unsigned char bytes[16];
45 for (
unsigned char& chr : bytes)
46 chr =
static_cast<unsigned char>(rand());
49 #define _2_BYTES_AT(b) (*reinterpret_cast<uint16_t*>(b)) 50 #define _4_BYTES_AT(b) (*reinterpret_cast<uint32_t*>(b)) 53 "blob:%08x-%04x-%04x-%04x-%08x%04x",
_4_BYTES_AT(bytes),
67 std::unordered_map<std::string, Member<MediaSource>>
68 MediaSource::media_sources_;
75 got_loaded_metadata_(false) {
80 DCHECK_EQ(0u, media_sources_.count(
url));
81 media_sources_[
url] =
this;
85 MediaSource::~MediaSource() {
86 DCHECK_EQ(1u, media_sources_.count(
url));
87 media_sources_.erase(
url);
97 LOG(ERROR) <<
"Unable to find a MediaPlayer instance to query";
103 auto support = player->DecodingInfo(info);
104 return support.supported;
109 if (media_sources_.count(url) == 0)
111 return media_sources_[
url];
115 EventTarget::Trace(tracer);
116 tracer->
Trace(&audio_buffer_);
117 tracer->
Trace(&video_buffer_);
118 tracer->
Trace(&video_);
122 const std::string&
type) {
126 R
"(Cannot call addSourceBuffer() unless MediaSource is "open".)"); 130 std::unordered_map<std::string, std::string> params; 134 "The given type ('" + type +
"') is not a valid MIME type.");
141 "No Demuxer implementation provided");
143 if (!
factory->IsTypeSupported(type) || codecs.empty() ||
144 codecs.find(
',') != std::string::npos) {
149 const bool is_video =
factory->IsCodecVideo(codecs);
152 if (!existing.
empty()) {
154 "Invalid SourceBuffer configuration");
157 if (!ret->Attach(type, player_, is_video)) {
171 R
"(Cannot call endOfStream() unless MediaSource is "open".)"); 173 if ((video_buffer_ && video_buffer_->updating) ||
174 (audio_buffer_ && audio_buffer_->updating)) {
177 "Cannot call endOfStream() when a SourceBuffer is updating.");
182 "Calling endOfStream() with an argument is not supported.");
186 ScheduleEvent<events::Event>(EventType::SourceEnded);
193 return player_ ? player_->
Duration() : NAN;
197 if (std::isnan(duration))
202 R
"(Cannot change duration unless MediaSource is "open".)"); 204 if ((video_buffer_ && video_buffer_->updating) ||
205 (audio_buffer_ && audio_buffer_->updating)) {
208 "Cannot change duration when a SourceBuffer is updating.");
219 <<
"MediaSource already attached to a <video> element.";
223 ScheduleEvent<events::Event>(EventType::SourceOpen);
228 <<
"MediaSource not attached to a <video> element.";
235 video_buffer_->Detach();
236 video_buffer_.reset();
239 audio_buffer_->Detach();
240 audio_buffer_.reset();
243 ScheduleEvent<events::Event>(EventType::SourceClose);
246 void MediaSource::OnLoadedMetaData(
double duration) {
248 if (got_loaded_metadata_) {
254 raise = video_buffer_.empty() != audio_buffer_.empty();
256 if (
raise && player_)
258 got_loaded_metadata_ =
true;
262 const uint8_t* data,
size_t size) {
285 NotImplemented(
"activeSourceBuffers");
286 NotImplemented(
"clearLiveSeekableRange");
287 NotImplemented(
"removeSourceBuffer");
288 NotImplemented(
"setLiveSeekableRange");
289 NotImplemented(
"sourceBuffers");
virtual BackingObjectFactoryBase * factory() const =0
#define END_ALLOW_COMPLEX_STATICS
std::string StringPrintf(const char *format,...)
static media::MediaPlayer * AnyMediaPlayer()
void Trace(const Traceable *ptr)
#define BEGIN_ALLOW_COMPLEX_STATICS
static JsError TypeError(const std::string &message)
static JsError DOMException(ExceptionCode code)
void AddListenerField(EventType type, Listener *on_field)