mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
[MSE] Add support for live seekable attribute
See https://github.com/w3c/media-source/issues/5
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user