The NetStream class opens a one-way streaming channel over a NetConnection. Use the NetStream class to do the following:
- Call
NetStream.play()
to play a media file from a local disk, a web server, or Flash Media Server. - Call
NetStream.publish()
to publish a video, audio, and data stream to Flash Media Server. - Call
NetStream.send()
to send data messages to all subscribed clients. - Call
NetStream.send()
to add metadata to a live stream. - Call
NetStream.appendBytes()
to pass ByteArray data into the NetStream.
Note: You cannot play and publish a stream over the same NetStream object.
Adobe AIR and Flash Player 9.0.115.0 and later versions support files derived from the standard MPEG-4 container format. These files include F4V, MP4, M4A, MOV, MP4V, 3GP, and 3G2 if they contain H.264 video, HEAAC v2 encoded audio, or both. H.264 delivers higher quality video at lower bit rates when compared to the same encoding profile in Sorenson or On2. AAC is a standard audio format defined in the MPEG-4 video standard. HE-AAC v2 is an extension of AAC that uses Spectral Band Replication (SBR) and Parametric Stereo (PS) techniques to increase coding efficiency at low bit rates.
For information about supported codecs and file formats, see the following:
- Flash Media Server documentation
- Exploring Flash Player support for high-definition H.264 video and AAC audio
- FLV/F4V open specification documents
Receiving data from a Flash Media Server stream, progressive F4V file, or progressive FLV file
Flash Media Server, F4V files, and FLV files can send event objects containing data at specific data points during streaming or playback. You can handle data from a stream or FLV file during playback in two ways:
-
Associate a client property with an event handler to receive the data object. Use the
NetStream.client
property to assign an object to call specific data handling functions. The object assigned to theNetStream.client
property can listen for the following data points:onCuePoint()
,onImageData()
,onMetaData()
,onPlayStatus()
,onSeekPoint()
,onTextData()
, andonXMPData()
. Write procedures within those functions to handle the data object returned from the stream during playback. See theNetStream.client
property for more information. -
Associate a client property with a subclass of the NetStream class, then write an event handler to receive the data object. NetStream is a sealed class, which means that properties or methods cannot be added to a NetStream object at runtime. However, you can create a subclass of NetStream and define your event handler in the subclass. You can also make the subclass dynamic and add the event handler to an instance of the subclass.
Wait to receive a NetGroup.Neighbor.Connect
event before you use the
object replication, direct routing, or posting APIs.
Note: To send data through an audio file, like an mp3 file, use the
Sound class to associate the audio file with a Sound object. Then, use the
Sound.id3
property to read metadata from the sound file.
Events:
asyncError | Dispatched when an exception is thrown asynchronously נthat is, from native asynchronous code. This event is dispatched when a server calls a method on the client that is not defined. | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
drmAuthenticate | Dispatched when a NetStream object tries to play a
digital rights management (DRM) encrypted content
that requires a user credential for authentication
before playing.
Use the | ||||||||||||
drmError | Dispatched when a NetStream object, trying to play a digital rights management (DRM) encrypted file, encounters a DRM-related error. For example, a DRMErrorEvent object is dispatched when the user authorization fails. This may be because the user has not purchased the rights to view the content or because the content provider does not support the viewing application. | ||||||||||||
drmStatus | Dispatched when the digital rights management (DRM) encrypted content begins playing (when the user is authenticated and authorized to play the content). DRMStatusEvent object contains information related to the voucher, such as whether the content is available offline or when the voucher expires and users can no longer view the content. | ||||||||||||
ioError | Dispatched when an input or output error occurs that causes a network operation to fail. | ||||||||||||
mediaTypeData | Dispatched when playing video content and certain type of messages are processed. A NetDataEvent is dispatched for the following messages:
Note: This event is not dispatched by content running in Flash Player in the browser on Android or Blackberry Tablet OS or by content running in AIR on iOS. | ||||||||||||
netStatus | Dispatched when a NetStream object is reporting
its status or error condition. The | ||||||||||||
onCuePoint | Establishes a listener to respond when an embedded cue point is reached while playing a video file. You can use the listener to trigger actions in your code when the video reaches a specific cue point, which lets you synchronize other actions in your application with video playback events. For information about video file formats supported by Flash Media Server, see the <a href="http://www.adobe.com/go/learn_fms_fileformats_en" scope="external">www.adobe.com/go/learn_fms_fileformats_en.
The associated event listener is triggered after a
call to the You can embed the following types of cue points in a video file:
The
You can define cue points in a video file when you first encode the file, or when you import a video clip in the Flash authoring tool by using the Video Import wizard. The Generally, to have your code respond to a specific
cue point at the time it occurs, use the
You can use the list of cue points provided to the
| ||||||||||||
onDRMContentData | Establishes a listener to respond when AIR extracts DRM content metadata embedded in a media file. A DRMContentData object contains the information needed to obtain a voucher required to play a DRM-protected media file. Use the DRMManager class to download the voucher with this information.
| ||||||||||||
onImageData | Establishes a listener to respond when Flash
Player receives image data as a byte array
embedded in a media file that is playing. The
image data can produce either JPEG, PNG, or GIF
content. Use the
The associated event listener is triggered after a
call to the The onImageData event object contains the image data as a byte array sent through an AMF0 data channel. | ||||||||||||
onMetaData | Establishes a listener to respond when Flash Player receives descriptive information embedded in the video being played. For information about video file formats supported by Flash Media Server, see the <a href="http://www.adobe.com/go/learn_fms_fileformats_en" scope="external">www.adobe.com/go/learn_fms_fileformats_en.
The Flash Video Exporter utility (version 1.1 or later) embeds a video's duration, creation date, data rates, and other information into the video file itself. Different video encoders embed different sets of meta data. The associated event listener is triggered after a
call to the In many cases, the duration value embedded in
stream metadata approximates the actual duration
but is not exact. In other words, it does not
always match the value of the The event object passed to the onMetaData event handler contains one property for each piece of data. | ||||||||||||
onPlayStatus | Establishes a listener to respond when a NetStream
object has completely played a stream. The
associated event object provides information in
addition to what's returned by the
This event can return an information object with the following properties:
| ||||||||||||
onSeekPoint | Called synchronously from The
| ||||||||||||
onTextData | Establishes a listener to respond when Flash
Player receives text data embedded in a media file
that is playing. The text data is in UTF-8 format
and can contain information about formatting based
on the 3GP timed text specification.
The associated event listener is triggered after a
call to the The onTextData event object contains one property for each piece of text data. | ||||||||||||
onXMPData | Establishes a listener to respond when Flash Player receives information specific to Adobe Extensible Metadata Platform (XMP) embedded in the video being played. For information about video file formats supported by Flash Media Server, see the <a href="http://www.adobe.com/go/learn_fms_fileformats_en" scope="external">www.adobe.com/go/learn_fms_fileformats_en.
The associated event listener is triggered after a
call to the The object passed to the | ||||||||||||
status | Dispatched when the application attempts to play
content encrypted with digital rights management
(DRM), by invoking the |
Constructor
new(connection:NetConnection, ?peerID:String)
Creates a stream that you can use to play media files and send data over a NetConnection object.
Parameters:
connection | A NetConnection object. |
---|---|
peerID | This optional parameter is available in Flash Player
10 and later, for use with RTMFP connections. (If
the value of the In most cases, a If you include this parameter in your constructor
statement but pass a value of |
Throws:
ArgumentError | The NetConnection instance is not connected. |
---|
Variables
read onlybufferLength:Float
The number of seconds of data currently in the buffer. You can use
this property with the bufferTime
property to estimate how close the
buffer is to being full נfor example, to display feedback to a user
who is waiting for data to be loaded into the buffer.
bufferTime:Float
Specifies how long to buffer messages before starting to display the
stream.
The default value is 0.1 (one-tenth of a second). To determine the
number of seconds currently in the buffer, use the bufferLength
property.
To play a server-side playlist, set bufferTime
to at least 1 second.
If you experience playback issues, increase the length of
bufferTime
.
Recorded content To avoid distortion when streaming pre-recorded
(not live) content, do not set the value of Netstream.bufferTime
to
0. By default, the application uses an input buffer for pre-recorded
content that queues the media data and plays the media properly. For
pre-recorded content, use the default setting or increase the buffer
time.
Live content When streaming live content, set the bufferTime
property to 0.
Starting with Flash Player 9.0.115.0, Flash Player no longer clears
the buffer when NetStream.pause()
is called. Before Flash Player
9.0.115.0, Flash Player waited for the buffer to fill up before
resuming playback, which often caused a delay.
For a single pause, the NetStream.bufferLength
property has a limit
of either 60 seconds or twice the value of NetStream.bufferTime
,
whichever value is higher. For example, if bufferTime
is 20 seconds,
Flash Player buffers until NetStream.bufferLength
is the higher
value of either 202 (40), or 60. In this case it buffers until
bufferLength
is 60. If bufferTime
is 40 seconds, Flash Player
buffers until bufferLength
is the higher value of 402 (80), or 60.
In this case it buffers until bufferLength
is 80 seconds.
The bufferLength
property also has an absolute limit. If any call to
pause()
causes bufferLength
to increase more than 600 seconds or
the value of bufferTime
* 2, whichever is higher, Flash Player
flushes the buffer and resets bufferLength
to 0. For example, if
bufferTime
is 120 seconds, Flash Player flushes the buffer if
bufferLength
reaches 600 seconds; if bufferTime
is 360 seconds,
Flash Player flushes the buffer if bufferLength
reaches 720 seconds.
Tip: You can use NetStream.pause()
in code to buffer data while
viewers are watching a commercial, for example, and then unpause when
the main video starts.
For more information about the new pause behavior, see <a href="http://www.adobe.com/go/learn_fms_smartpause_en" scope="external">http://www.adobe.com/go/learn_fms_smartpause_en</a>.
Flash Media Server. The buffer behavior depends on whether the
buffer time is set on a publishing stream or a subscribing stream. For
a publishing stream, bufferTime
specifies how long the outgoing
buffer can grow before the application starts dropping frames. On a
high-speed connection, buffer time is not a concern; data is sent
almost as quickly as the application can buffer it. On a slow
connection, however, there can be a significant difference between how
fast the application buffers the data and how fast it is sent to the
client.
For a subscribing stream, bufferTime
specifies how long to buffer
incoming data before starting to display the stream.
When a recorded stream is played, if bufferTime
is 0, Flash sets it
to a small value (approximately 10 milliseconds). If live streams are
later played (for example, from a playlist), this buffer time
persists. That is, bufferTime
remains nonzero for the stream.
read onlybytesLoaded:Int
The number of bytes of data that have been loaded into the
application. You can use this property with the bytesTotal
property
to estimate how close the buffer is to being full נfor example, to
display feedback to a user who is waiting for data to be loaded into
the buffer.
checkPolicyFile:Bool
Specifies whether the application tries to download a cross-domain
policy file from the loaded video file's server before beginning to
load the video file. Use this property for progressive video download,
and to load files that are outside the calling SWF file's own domain.
This property is ignored when you are using RTMP.
Set this property to true
to call BitmapData.draw()
on a video
file loaded from a domain outside that of the calling SWF. The
BitmapData.draw()
method provides pixel-level access to the video.
If you call BitmapData.draw()
without setting the checkPolicyFile
property to true
at loading time, you can get a SecurityError
exception because the required policy file was not downloaded.
Do not set this property to true unless you want pixel-level access to the video you are loading. Checking for a policy file consumes network bandwidth and can delay the start of your download.
When you call the NetStream.play()
method with checkPolicyFile
set
to true
, Flash Player or the AIR runtime must either successfully
download a relevant cross-domain policy file or determine that no such
policy file exists before it begins downloading. To verify the
existence of a policy file, Flash Player or the AIR runtime performs
the following actions, in this order:
- The application considers policy files that have already been downloaded.
- The application tries to download any pending policy files specified
in calls to the
Security.loadPolicyFile()
method. - The application tries to download a policy file from the default
location that corresponds to the URL you passed to
NetStream.play()
, which is/crossdomain.xml
on the same server as that URL.
In all cases, Flash Player or Adobe AIR requires that an appropriate
policy file exist on the video's server, that it provide access to the
object at the URL you passed to play()
based on the policy file's
location, and that it allow the domain of the calling code's file to
access the video, through one or more <allow-access-from>
tags.
If you set checkPolicyFile
to true
, the application waits until
the policy file is verified before downloading the video. Wait to
perform any pixel-level operations on the video data, such as calling
BitmapData.draw()
, until you receive onMetaData
or NetStatus
events from your NetStream object.
If you set checkPolicyFile
to true
but no relevant policy file is
found, you won't receive an error until you perform an operation that
requires a policy file, and then the application throws a
SecurityError exception.
Be careful with checkPolicyFile
if you are downloading a file from a
URL that uses server-side HTTP redirects. The application tries to
retrieve policy files that correspond to the initial URL that you
specify in NetStream.play()
. If the final file comes from a
different URL because of HTTP redirects, the initially downloaded
policy files might not be applicable to the file's final URL, which is
the URL that matters in security decisions.
For more information on policy files, see "Website controls (policy files)" in the OpenFL Developer's Guide and the Flash Player Developer Center Topic: Security.
client:Dynamic
Specifies the object on which callback methods are invoked to handle
streaming or F4V/FLV file data. The default object is this
, the
NetStream object being created. If you set the client
property to
another object, callback methods are invoked on that other object. The
NetStream.client
object can call the following functions and
receive an associated data object: onCuePoint()
, onImageData()
,
onMetaData()
, onPlayStatus()
, onSeekPoint()
, onTextData()
, and
onXMPData()
.
To associate the client
property with an event handler:
- Create an object and assign it to the
client
property of the NetStream object:
var customClient = new Object();
my_netstream.client = customClient;
- Assign a handler function for the desired data event as a property of the client object:
customClient.onImageData = onImageDataHandler;
- Write the handler function to receive the data event object, such as:
public function onImageDataHandler(imageData:Object):void {
trace("imageData length: " + imageData.data.length);
}
When data is passed through the stream or during playback, the data
event object (in this case the imageData
object) is populated with
the data. See the onImageData
description, which includes a full
example of an object assigned to the client
property.
To associate the client
property with a subclass:
- Create a subclass with a handler function to receive the data event object:
class CustomClient {
public function onMetaData(info:Object):void {
trace("metadata: duration=" + info.duration + " framerate=" + info.framerate);
}
- Assign an instance of the subclass to the
client
property of the NetStream object:
my_netstream.client = new CustomClient();
When data is passed through the stream or during playback, the data
event object (in this case the info
object) is populated with the
data. See the class example at the end of the NetStream class, which
shows the assignment of a subclass instance to the client
property.
Throws:
TypeError | The |
---|
read onlycurrentFPS:Float
The number of frames per second being displayed. If you are exporting video files to be played back on a number of systems, you can check this value during testing to help you determine how much compression to apply when exporting the file.
read onlyliveDelay:Float
The number of seconds of data in the subscribing stream's buffer in live (unbuffered) mode. This property specifies the current network transmission delay (lag time). This property is intended primarily for use with a server such as Flash Media Server; for more information, see the class description.
You can get the value of this property to roughly gauge the transmission quality of the stream and communicate it to the user.
read onlyobjectEncoding:ObjectEncoding
The object encoding (AMF version) for this NetStream object. The
NetStream object inherits its objectEncoding
value from the
associated NetConnection object. It's important to understand this
property if your ActionScript 3.0 SWF file needs to communicate with
servers released prior to Flash Player 9. For more information, see
the objectEncoding
property description in the NetConnection class.
The value of this property depends on whether the stream is local or
remote. Local streams, where null
was passed to the
NetConnection.connect()
method, return the value of
NetConnection.defaultObjectEncoding
. Remote streams, where you are
connecting to a server, return the object encoding of the connection
to the server.
If you try to read this property when not connected, or if you try to change this property, the application throws an exception.
soundTransform:SoundTransform
Controls sound in this NetStream object. For more information, see the SoundTransform class.
read onlytime:Float
The position of the playhead, in seconds. Flash Media Server For a subscribing stream, the number of seconds the stream has been playing. For a publishing stream, the number of seconds the stream has been publishing. This number is accurate to the thousandths decimal place; multiply by 1000 to get the number of milliseconds the stream has been playing.
For a subscribing stream, if the server stops sending data but the
stream remains open, the value of the time
property stops advancing.
When the server begins sending data again, the value continues to
advance from the point at which it stopped (when the server stopped
sending data).
The value of time
continues to advance when the stream switches from
one playlist element to another. This property is set to 0 when
NetStream.play()
is called with reset
set to 1
or true
, or
when NetStream.close()
is called.
Methods
close():Void
Stops playing all data on the stream, sets the time
property to 0,
and makes the stream available for another use. This method also
deletes the local copy of a video file that was downloaded through
HTTP. Although the application deletes the local copy of the file that
it creates, a copy might persist in the cache directory. If you must
completely prevent caching or local storage of the video file, use
Flash Media Server.
When using Flash Media Server, this method is invoked implicitly when
you call NetStream.play()
from a publishing stream or
NetStream.publish()
from a subscribing stream. Please note that:
- If
close()
is called from a publishing stream, the stream stops publishing and the publisher can now use the stream for another purpose. Subscribers no longer receive anything that was being published on the stream, because the stream has stopped publishing. - If
close()
is called from a subscribing stream, the stream stops playing for the subscriber, and the subscriber can use the stream for another purpose. Other subscribers are not affected. - You can stop a subscribing stream from playing, without closing the
stream or changing the stream type by using
openfl.net.NetStream.play(false)
.
dispose():Void
Releases all the resources held by the NetStream object.
The dispose()
method is similar to the close
method. The main difference
between the two methods is that dispose()
releases the memory used to display
the current video frame. If that frame is currently displayed on screen, the
display will go blank. The close()
method does not blank the display because it
does not release this memory.
pause():Void
Pauses playback of a video stream. Calling this method does nothing if
the video is already paused. To resume play after pausing a video,
call resume()
. To toggle between pause and play (first pausing the
video, then resuming), call togglePause()
.
Starting with Flash Player 9.0.115.0, Flash Player no longer clears
the buffer when NetStream.pause()
is called. This behavior is called
"smart pause". Before Flash Player 9.0.115.0, Flash Player waited for
the buffer to fill up before resuming playback, which often caused a
delay.
Note: For backwards compatibility, the "NetStream.Buffer.Flush"
event (see the NetStatusEvent.info
property) still fires, although
the server does not flush the buffer.
For a single pause, the NetStream.bufferLength
property has a limit
of either 60 seconds or twice the value of NetStream.bufferTime
,
whichever value is higher. For example, if bufferTime
is 20 seconds,
Flash Player buffers until NetStream.bufferLength
is the higher
value of either 20~~2 (40), or 60, so in this case it buffers until
bufferLength
is 60. If bufferTime
is 40 seconds, Flash Player
buffers until bufferLength
is the higher value of 40~~2 (80), or 60,
so in this case it buffers until bufferLength
is 80 seconds.
The bufferLength
property also has an absolute limit. If any call to
pause()
causes bufferLength
to increase more than 600 seconds or
the value of bufferTime
~~ 2, whichever is higher, Flash Player
flushes the buffer and resets bufferLength
to 0. For example, if
bufferTime
is 120 seconds, Flash Player flushes the buffer if
bufferLength
reaches 600 seconds; if bufferTime
is 360 seconds,
Flash Player flushes the buffer if bufferLength
reaches 720 seconds.
Tip: You can use NetStream.pause()
in code to buffer data while
viewers are watching a commercial, for example, and then unpause when
the main video starts.
play(url:String, ?p1:Unknown, ?p2:Unknown, ?p3:Unknown, ?p4:Unknown, ?p5:Unknown):Void
Plays a media file from a local directory or a web server; plays a
media file or a live stream from Flash Media Server. Dispatches a
NetStatusEvent
object to report status and error messages.
For information about supported codecs and file formats, see the
following:
- Flash Media Server documentation
- Exploring Flash Player support for high-definition H.264 video and AAC audio
- FLV/F4V open specification documents
Workflow for playing a file or live stream
- Create a NetConnection object and call
NetConnection.connect()
. To play a file from a local directory or web server, pass null.
To play a recorded file or live stream from Flash Media Server, pass
the URI of a Flash Media Server application.
2. Call NetConnection.addEventListener(NetStatusEvent.NET_STATUS,
netStatusHandler)
to listen for NetStatusEvent events.
3. On "NetConnection.Connect.Success"
, create a NetStream object and
pass the NetConnection object to the constructor.
4. Create a Video object and call Video.attachNetStream()
and pass
the NetStream object.
5. Call NetStream.play()
.
To play a live stream, pass the stream name passed to the
NetStream.publish()
method.
To play a recorded file, pass the file name.
6. Call addChild()
and pass the Video object to display the video.
Note: To see sample code, scroll to the example at the bottom of this page.
Enable Data Generation Mode
Call play(null)
to enable "Data Generation Mode". In this mode, call
the appendBytes()
method to deliver data to the NetStream. Use Data
Generation Mode to stream content over HTTP from the Adobe HTTP
Dynamic Streaming Origin Module on an Apache HTTP Server. HTTP Dynamic
Streaming lets clients seek quickly to any point in a file. The Open
Source Media Framework (OSMF) supports HTTP Dynamic Streaming for vod
and live streams. For examples of how to use NetStream Data Generation
Mode, download the <a href="http://www.opensourcemediaframework.com"
scope="external">OSMF source. For more information about HTTP
Dynamic Streaming, see <a
href="http://www.adobe.com/go/learn_fms_http_en" scope="external">HTTP
Dynamic Streaming.
When you use this method without Flash Media Server, there are
security considerations. A file in the local-trusted or
local-with-networking sandbox can load and play a video file from the
remote sandbox, but cannot access the remote file's data without
explicit permission in the form of a URL policy file. Also, you can
prevent a SWF file running in Flash Player from using this method by
setting the allowNetworking
parameter of the the object
and
embed
tags in the HTML page that contains the SWF content. For more
information related to security, see the Flash Player Developer Center
Topic: Security.
Throws:
ArgumentError | At least one parameter must be specified. |
---|---|
Error | The NetStream Object is invalid. This may be due to a failed NetConnection. |
SecurityError | Local untrusted SWF files cannot communicate with the Internet. You can work around this restriction by reclassifying this SWF file as local-with-networking or trusted. |
Events:
status | Dispatched when attempting to play content encrypted
with digital rights management (DRM). The value of the
|
---|
resume():Void
Resumes playback of a video stream that is paused. If the video is already playing, calling this method does nothing.
seek(time:Float):Void
Seeks the keyframe (also called an I-frame in the video industry) closest to the specified location. The keyframe is placed at an offset, in seconds, from the beginning of the stream. Video streams are usually encoded with two types of frames, keyframes (or I-frames) and P-frames. A keyframe contains an entire image, while a P-frame is an interim frame that provides additional video information between keyframes. A video stream typically has a keyframe every 10-50 frames.
Flash Media Server has several types of seek behavior: enhanced seeking and smart seeking.
Enhanced seeking
Enhanced seeking is enabled by default. To disable enhanced seeking,
on Flash Media Server set the EnhancedSeek
element in the
Application.xml
configuration file to false
.
If enhanced seeking is enabled, the server generates a new keyframe at
offset
based on the previous keyframe and any intervening P-frames.
However, generating keyframes creates a high processing load on the
server and distortion might occur in the generated keyframe. If the
video codec is On2, the keyframe before the seek point and any
P-frames between the keyframe and the seek point are sent to the
client.
If enhanced seeking is disabled, the server starts streaming from the nearest keyframe. For example, suppose a video has keyframes at 0 seconds and 10 seconds. A seek to 4 seconds causes playback to start at 4 seconds using the keyframe at 0 seconds. The video stays frozen until it reaches the next keyframe at 10 seconds. To get a better seeking experience, you need to reduce the keyframe interval. In normal seek mode, you cannot start the video at a point between the keyframes.
Smart seeking
To enable smart seeking, set NetStream.inBufferSeek
to true
.
Smart seeking allows Flash Player to seek within an existing back
buffer and forward buffer. When smart seeking is disabled, each time
seek()
is called Flash Player flushes the buffer and requests data
from the server. For more information, see NetStream.inBufferSeek
.
Seeking in Data Generation Mode
When you call seek()
on a NetStream in Data Generation Mode, all
bytes passed to appendBytes()
are discarded (not placed in the
buffer, accumulated in the partial message FIFO, or parsed for seek
points) until you call
appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN)
or
appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK)
to reset
the parser. For information about Data Generation Mode, see
NetStream.play()
.
Parameters:
offset | The approximate time value, in seconds, to move to in a
video file. With Flash Media Server, if |
---|
togglePause():Void
Pauses or resumes playback of a stream. The first time you call this method, it pauses play; the next time, it resumes play. You could use this method to let users pause or resume playback by pressing a single button.