/*
* Copyright 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.gwt.media.client;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.MediaElement;
import com.google.gwt.dom.client.SourceElement;
import com.google.gwt.event.dom.client.CanPlayThroughEvent;
import com.google.gwt.event.dom.client.CanPlayThroughHandler;
import com.google.gwt.event.dom.client.EndedEvent;
import com.google.gwt.event.dom.client.EndedHandler;
import com.google.gwt.event.dom.client.HasAllMediaHandlers;
import com.google.gwt.event.dom.client.LoadedMetadataEvent;
import com.google.gwt.event.dom.client.LoadedMetadataHandler;
import com.google.gwt.event.dom.client.ProgressEvent;
import com.google.gwt.event.dom.client.ProgressHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.media.dom.client.MediaError;
import com.google.gwt.media.dom.client.TimeRanges;
import com.google.gwt.user.client.ui.FocusWidget;
/**
* <p>
* A widget representing a media element.
*
* <p>
* <span style="color:red">Experimental API: This API is still under development
* and is subject to change. </span>
* </p>
*/
public abstract class MediaBase extends FocusWidget
implements HasAllMediaHandlers {
/**
* Protected constructor.
*/
protected MediaBase(MediaElement element) {
setElement(element);
}
@Override
public HandlerRegistration addCanPlayThroughHandler(
CanPlayThroughHandler handler) {
return addBitlessDomHandler(handler, CanPlayThroughEvent.getType());
}
@Override
public HandlerRegistration addEndedHandler(EndedHandler handler) {
return addBitlessDomHandler(handler, EndedEvent.getType());
}
@Override
public HandlerRegistration addProgressHandler(ProgressHandler handler) {
return addBitlessDomHandler(handler, ProgressEvent.getType());
}
@Override
public HandlerRegistration addLoadedMetadataHandler(LoadedMetadataHandler handler) {
return addBitlessDomHandler(handler, LoadedMetadataEvent.getType());
}
/**
* Add a source element to this media. The browser will request source files
* from the server until it finds one it can play.
*
* <p>
* Only use this method if you do not know the type of the source file, as the
* browser cannot determine the format from the filename and must download
* each source until a compatible one is found. Instead, you should specify
* the type for the media using {@link #addSource(String, String)} so the
* browser can choose a source file without downloading the file.
* </p>
*
* @param url a String URL
* @see #addSource(String, String)
*/
public SourceElement addSource(String url) {
SourceElement elem = Document.get().createSourceElement();
elem.setSrc(url);
getElement().appendChild(elem);
return elem;
}
/**
* Add a source element to this media, specifying the type (format) of the
* media. The browser will choose a supported source file and download it.
*
* <p>
* The type is the format or encoding of the media represented by the source
* element. For example, the type of an
* {@link com.google.gwt.dom.client.AudioElement} could be one of
* {@value com.google.gwt.dom.client.AudioElement#TYPE_OGG},
* {@link com.google.gwt.dom.client.AudioElement#TYPE_MP3}, or
* {@link com.google.gwt.dom.client.AudioElement#TYPE_WAV}.
* </p>
*
* <p>
* You can also add the codec information to the type, giving the browser even
* more information about whether or not it can play the file (Example: "
* <code>audio/ogg; codec=vorbis</code>");
* </p>
*
* @param url a String URL
* @param type the type (format) of the media
* @see #getSrc()
*/
public SourceElement addSource(String url, String type) {
SourceElement elem = addSource(url);
elem.setType(type);
return elem;
}
/**
* Returns {@code true} if the native player is capable of playing content of
* the given MIME type.
*
* @param type a String representing a MIME type
* @return one of {@link MediaElement#CAN_PLAY_PROBABLY},
* {@link MediaElement#CAN_PLAY_MAYBE}, or
* {@link MediaElement#CANNOT_PLAY}
*/
public String canPlayType(String type) {
return getMediaElement().canPlayType(type);
}
/**
* Returns a {@link TimeRanges} object indicating which portions of the source
* have been buffered locally.
*
* @return a {@link TimeRanges} instance, or {@code null}.
*/
public TimeRanges getBuffered() {
return getMediaElement().getBuffered();
}
/**
* Returns the URL of the current media source, or the empty String if no
* source is set.
*
* @return a String URL
*/
public String getCurrentSrc() {
return getMediaElement().getCurrentSrc();
}
/**
* Returns the current time within the source media stream.
*
* @return the time, in seconds, as a double
*
* @see #setCurrentTime(double)
*/
public double getCurrentTime() {
return getMediaElement().getCurrentTime();
}
/**
* Returns the default playback rate, where 1.0 corresponds to normal
* playback. If no rate has been set, 1.0 is returned.
*
* @return the current default playback rate, or 1.0 if it has not been set
*
* @see #setDefaultPlaybackRate(double)
*/
public double getDefaultPlaybackRate() {
return getMediaElement().getDefaultPlaybackRate();
}
/**
* Returns the duration of the source media stream, in seconds. If the
* duration is unknown, {@link Double#NaN} is returned. For unbounded media
* streams, {@link Double#POSITIVE_INFINITY} is returned.
*
* @return a positive duration in seconds, NaN, or Infinity
*/
public double getDuration() {
return getMediaElement().getDuration();
}
/**
* Returns the type of error that has occurred while attempting to load and
* play the media. If no error has occurred, {@code null} is returned.
*
* @return a {@link MediaError} instance, or {@code null}
*/
public MediaError getError() {
return getMediaElement().getError();
}
/**
* Returns the time to which the media stream was seeked at the time it was
* loaded, in seconds, or 0.0 if the position is unknown.
*
* @return the initial time, or 0.0 if unknown
*/
public double getInitialTime() {
return getMediaElement().getInitialTime();
}
/**
* Returns the attached Media Element.
*
* @return the Media Element
*/
public MediaElement getMediaElement() {
return this.getElement().cast();
}
/**
* Returns the network state, one of {@link MediaElement#NETWORK_EMPTY},
* {@link MediaElement#NETWORK_IDLE}, {@link MediaElement#NETWORK_LOADING}, or
* {@link MediaElement#NETWORK_NO_SOURCE}.
*
* @return an integer constant indicating the network state
*
* @see MediaElement#NETWORK_EMPTY
* @see MediaElement#NETWORK_IDLE
* @see MediaElement#NETWORK_LOADING
* @see MediaElement#NETWORK_NO_SOURCE
*/
public int getNetworkState() {
return getMediaElement().getNetworkState();
}
/**
* Returns the playback rate, where 1.0 corresponds to normal playback. If the
* rate has not been set, 1.0 is returned.
*
* @return the playback rate, if known, otherwise 1.0
*
* @see #setPlaybackRate(double)
*/
public double getPlaybackRate() {
return getMediaElement().getPlaybackRate();
}
/**
* Returns a {@link TimeRanges} object indicating which portions of the source
* have been played.
*
* @return a {@link TimeRanges} instance, or {@code null}.
*/
public TimeRanges getPlayed() {
return getMediaElement().getPlayed();
}
/**
* Returns the preload setting, one of {@link MediaElement#PRELOAD_AUTO},
* {@link MediaElement#PRELOAD_METADATA}, or
* {@link MediaElement#PRELOAD_NONE}.
*
* @return the preload setting
*
* @see #setPreload(String)
* @see MediaElement#PRELOAD_AUTO
* @see MediaElement#PRELOAD_METADATA
* @see MediaElement#PRELOAD_NONE
*/
public String getPreload() {
return getMediaElement().getPreload();
}
/**
* Returns the current state of the media with respect to rendering the
* current playback position, as one of the constants
* {@link MediaElement#HAVE_CURRENT_DATA},
* {@link MediaElement#HAVE_ENOUGH_DATA},
* {@link MediaElement#HAVE_FUTURE_DATA}, {@link MediaElement#HAVE_METADATA},
* or {@link MediaElement#HAVE_NOTHING} .
*
* @return an integer constant indicating the ready state
*
* @see MediaElement#HAVE_CURRENT_DATA
* @see MediaElement#HAVE_ENOUGH_DATA
* @see MediaElement#HAVE_FUTURE_DATA
* @see MediaElement#HAVE_METADATA
* @see MediaElement#HAVE_NOTHING
*/
public int getReadyState() {
return getMediaElement().getReadyState();
}
/**
* Returns a {@link TimeRanges} object indicating which portions of the source
* are seekable.
*
* @return a {@link TimeRanges} instance, or {@code null}.
*/
public TimeRanges getSeekable() {
return getMediaElement().getSeekable();
}
/**
* Returns the source URL for the media, or {@code null} if none is set.
*
* @return a String URL or {@code null}
*
* @see #setSrc(String)
*/
public String getSrc() {
return getMediaElement().getSrc();
}
/**
* Returns the time corresponding to the zero time in the media timeline,
* measured in seconds since midnight, January 1 1970 UTC, or
* {@link Double#NaN} if none is specified.
*
* @return the start time
*/
public double getStartOffsetTime() {
return getMediaElement().getStartOffsetTime();
}
/**
* Returns the current audio volume setting for the media, as a number between
* 0.0 and 1.0.
*
* @return a number between 0.0 (silent) and 1.0 (loudest)
*
* @see #setVolume(double)
*/
public double getVolume() {
return getMediaElement().getVolume();
}
/**
* Returns {@code true} if the media player should display interactive
* controls (for example, to control play/pause, seek position, and volume),
* {@code false} otherwise.
*
* @return whether controls should be displayed
*
* @see #setControls(boolean)
*/
public boolean hasControls() {
return getMediaElement().hasControls();
}
/**
* Returns {@code true} if playback has reached the end of the media, {@code
* false} otherwise.
*
* @return whether playback has ended
*/
public boolean hasEnded() {
return getMediaElement().hasEnded();
}
/**
* Returns {@code true} if autoplay is enabled, {@code false} otherwise. When
* autoplay is enabled, the user agent will begin playback automatically as
* soon as it can do so without stopping.
*
* @return the autoplay setting
*
* @see #setAutoplay(boolean)
*/
public boolean isAutoplay() {
return getMediaElement().isAutoplay();
}
/**
* Returns {@code true} if the user agent is to seek back to the start of the
* media once playing has ended, {@code false} otherwise.
*
* @return the loop setting
*
* @see #setLoop(boolean)
*/
public boolean isLoop() {
return getMediaElement().isLoop();
}
/**
* Returns {@code true} if the volume is to be muted (overriding the normal
* volume setting), {@code false} otherwise.
*
* @return the muting setting
*
* @see #setMuted(boolean)
* @see #getVolume()
* @see #setVolume(double)
*/
public boolean isMuted() {
return getMediaElement().isMuted();
}
/**
* Returns {@code true} if playback is paused, {@code false} otherwise.
*
* @return the paused setting
*
* @see #pause()
* @see #play()
*/
public boolean isPaused() {
return getMediaElement().isPaused();
}
/**
* Returns {@code true} if the playback position is in the process of changing
* discontinuously, e.g., by use of the interactive controls, {@code false}
* otherwise.
*
* @return the seeking status
*
* @see #setControls(boolean)
* @see #hasControls()
*/
public boolean isSeeking() {
return getMediaElement().isSeeking();
}
/**
* Causes the resource to be loaded.
*/
public void load() {
getMediaElement().load();
}
/**
* Causes playback of the resource to be paused.
*/
public void pause() {
getMediaElement().pause();
}
/**
* Causes playback of the resource to be started or resumed.
*/
public void play() {
getMediaElement().play();
}
/**
* Remove the specified {@link SourceElement} from this media. If the source
* element is not a child of this widget, it will not be removed.
*
* @param source the source element to remove
* @see #addSource(String, String)
*/
public void removeSource(SourceElement source) {
getElement().removeChild(source);
}
/**
* Enables or disables autoplay of the resource.
*
* @param autoplay if {@code true}, enable autoplay
*
* @see #isAutoplay()
*/
public void setAutoplay(boolean autoplay) {
getMediaElement().setAutoplay(autoplay);
}
/**
* Enables or disables interactive controls.
*
* @param controls if {@code true}, enable controls
*
* @see #hasControls()
*/
public void setControls(boolean controls) {
getMediaElement().setControls(controls);
}
/**
* Sets the current playback time within the media stream, in seconds.
*
* @param time a number within the ranges given by {@link #getSeekable()}
*
* @see #getCurrentTime()
*/
public void setCurrentTime(double time) {
getMediaElement().setCurrentTime(time);
}
/**
* Sets the default playback rate.
*
* @param rate a double value
*
* @see #getDefaultPlaybackRate()
*/
public void setDefaultPlaybackRate(double rate) {
getMediaElement().setDefaultPlaybackRate(rate);
}
/**
* Enables or disables looping.
*
* @param loop if {@code true}, enable looping
*
* @see #isLoop()
*/
public final void setLoop(boolean loop) {
getMediaElement().setLoop(loop);
}
/**
* Enables or disables muting.
*
* @param muted if {@code true}, enable muting
*
* @see #isMuted()
*/
public void setMuted(boolean muted) {
getMediaElement().setMuted(muted);
}
/**
* Sets the playback rate.
*
* @param rate a double value
*
* @see #getPlaybackRate()
*/
public void setPlaybackRate(double rate) {
getMediaElement().setPlaybackRate(rate);
}
/**
* Changes the preload setting to one of {@link MediaElement#PRELOAD_AUTO},
* {@link MediaElement#PRELOAD_METADATA}, or
* {@link MediaElement#PRELOAD_NONE}.
*
* @param preload a String constants
*
* @see #getPreload()
* @see #setPreload(String)
* @see MediaElement#PRELOAD_AUTO
* @see MediaElement#PRELOAD_METADATA
* @see MediaElement#PRELOAD_NONE
*/
public void setPreload(String preload) {
getMediaElement().setPreload(preload);
}
/**
* Sets the source URL for the media.
*
* <p>
* Support for different media types varies between browsers. Instead of using
* this method, you should encode your media in multiple formats and add all
* of them using {@link #addSource(String, String)} so the browser can choose
* a source that it supports.
* </p>
*
* @param url a String URL
*
* @see #getSrc()
* @see #addSource(String, String)
*/
public void setSrc(String url) {
getMediaElement().setSrc(url);
}
/**
* Sets the playback volume.
*
* @param volume a value between 0.0 (silent) and 1.0 (loudest)
*
* @see #getVolume()
*/
public void setVolume(double volume) {
getMediaElement().setVolume(volume);
}
}