[MSE] Add support for live seekable attribute

See https://github.com/w3c/media-source/issues/5
This commit is contained in:
trav90
2017-06-19 03:00:11 -05:00
committed by Roy Tam
parent 889acf3146
commit f25dcba94a
4 changed files with 84 additions and 0 deletions
+52
View File
@@ -338,6 +338,58 @@ MediaSource::Enabled(JSContext* cx, JSObject* aGlobal)
return Preferences::GetBool("media.mediasource.enabled");
}
void
MediaSource::SetLiveSeekableRange(double aStart, double aEnd, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
// 1. If the readyState attribute is not "open" then throw an InvalidStateError
// exception and abort these steps.
// 2. If the updating attribute equals true on any SourceBuffer in
// sourceBuffers, then throw an InvalidStateError exception and abort these
// steps.
if (mReadyState != MediaSourceReadyState::Open ||
mSourceBuffers->AnyUpdating()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
// 3. If start is negative or greater than end, then throw a TypeError
// exception and abort these steps.
if (aStart < 0 || aStart > aEnd) {
aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
return;
}
// 4. Set live seekable range to be a new normalized TimeRanges object
// containing a single range whose start position is start and end position is
// end.
mLiveSeekableRange =
Some(media::TimeInterval(media::TimeUnit::FromSeconds(aStart),
media::TimeUnit::FromSeconds(aEnd)));
}
void
MediaSource::ClearLiveSeekableRange(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
// 1. If the readyState attribute is not "open" then throw an InvalidStateError
// exception and abort these steps.
// 2. If the updating attribute equals true on any SourceBuffer in
// sourceBuffers, then throw an InvalidStateError exception and abort these
// steps.
if (mReadyState != MediaSourceReadyState::Open ||
mSourceBuffers->AnyUpdating()) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
// 3. If live seekable range contains a range, then set live seekable range to
// be a new empty TimeRanges object.
mLiveSeekableRange.reset();
}
bool
MediaSource::Attach(MediaSourceDecoder* aDecoder)
{
+13
View File
@@ -19,6 +19,7 @@
#include "nsID.h"
#include "nsISupports.h"
#include "nscore.h"
#include "TimeUnits.h"
struct JSContext;
class JSObject;
@@ -64,6 +65,10 @@ public:
void RemoveSourceBuffer(SourceBuffer& aSourceBuffer, ErrorResult& aRv);
void EndOfStream(const Optional<MediaSourceEndOfStreamError>& aError, ErrorResult& aRv);
void SetLiveSeekableRange(double aStart, double aEnd, ErrorResult& aRv);
void ClearLiveSeekableRange(ErrorResult& aRv);
static bool IsTypeSupported(const GlobalObject&, const nsAString& aType);
static bool Enabled(JSContext* cx, JSObject* aGlobal);
@@ -118,6 +123,12 @@ public:
// buffered data. Used for debugging purposes.
void GetMozDebugReaderData(nsAString& aString);
bool HasLiveSeekableRange() const { return mLiveSeekableRange.isSome(); }
media::TimeInterval LiveSeekableRange() const
{
return mLiveSeekableRange.value();
}
private:
// MediaSourceDecoder uses DurationChange to set the duration
// without hitting the checks in SetDuration.
@@ -154,6 +165,8 @@ private:
nsRefPtr<nsIPrincipal> mPrincipal;
MediaSourceReadyState mReadyState;
Maybe<media::TimeInterval> mLiveSeekableRange;
bool mFirstSourceBufferInitialized;
};
@@ -91,6 +91,21 @@ MediaSourceDecoder::GetSeekable()
// Return empty range.
} else if (duration > 0 && mozilla::IsInfinite(duration)) {
media::TimeIntervals buffered = mReader->GetBuffered();
// 1. If live seekable range is not empty:
if (mMediaSource->HasLiveSeekableRange()) {
// 1. Let union ranges be the union of live seekable range and the
// HTMLMediaElement.buffered attribute.
media::TimeIntervals unionRanges =
buffered + mMediaSource->LiveSeekableRange();
// 2. Return a single range with a start time equal to the earliest start
// time in union ranges and an end time equal to the highest end time in
// union ranges and abort these steps.
seekable +=
media::TimeInterval(unionRanges.GetStart(), unionRanges.GetEnd());
return seekable;
}
if (buffered.Length()) {
seekable +=
media::TimeInterval(media::TimeUnit::FromSeconds(0), buffered.GetEnd());
+4
View File
@@ -34,6 +34,10 @@ interface MediaSource : EventTarget {
void removeSourceBuffer(SourceBuffer sourceBuffer);
[Throws]
void endOfStream(optional MediaSourceEndOfStreamError error);
[Throws]
void setLiveSeekableRange(double start, double end);
[Throws]
void clearLiveSeekableRange();
static boolean isTypeSupported(DOMString type);
[ChromeOnly]
readonly attribute DOMString mozDebugReaderData;