DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 14.13 Seeking Relative to the Total Stream Length

14.13.1 Problem

You want to seek a stream based on the total length of the stream.

14.13.2 Solution

Get the stream length from the server and then use the seek( ) method.

14.13.3 Discussion

A problem arises when you want to seek within a stream relative to the total length of the stream. For example, if you want to create a slider that a user can move to seek through a stream, you must determine the total length of a stream. There is no client-side property or method that returns that information. However, you can write a server-side function to return a stream's length using the Stream.length( ) method. Here are the steps to return a stream's length from the server:

  1. In the server-side .asc file (either the main.asc file or another .asc file that is loaded by main.asc) create a method for client objects that takes the name of a stream and returns the length of that stream (see Recipe 14.4). Most often, you assign methods to a client in the application.onConnect( ) method.

    // The application.onConnect(  ) method is invoked automatically whenever a new
    // client connects to the FlashCom application. The client object is created and
    // passed as a parameter to the method.
    application.onConnect = function (newClient) {
    
      // Create a custom getStreamLength(  ) method for each client. The method takes
      // the name of a stream as a parameter.
      newClient.getStreamLength = function (streamName) {
        // Return the length of the requested stream.
        return Stream.length(streamName);
      };
    };
  2. In the client-side ActionScript, connect to the FlashCom application:

    myConnection = new NetConnection(  );
    myConnection.connect("rtmp:/myApp");
  3. Create a response object to handle the result from the call to getStreamLength( ). A response object is an object created from the Object class, for which you have defined an onResult( ) method. When the onResult( ) method is invoked by a response from the FlashCom server, a result is returned from FlashCom and passed to the method as a parameter:

    myResponse = new Object(  );
    myResponse.onResult = function (result) {
      _root.streamLength = result;
      trace("the stream length is: " + result);
    };
  4. Once a connection is established and a response object is defined, call the server-side getStreamLength( ) method using the call( ) method of the client-side connection object. Specify that any response should be handled by the response object you created in the previous step and pass along the name of the stream as a parameter.

    myConnection.call("getStreamLength", myResponse, "myStreamName");

Once you have retrieved the total length of the stream, you can use that value in conjunction with a slider controller to determine values to pass to the seek( ) method. Here is an example:

// Create the connection.
myConnection = new NetConnection(  );
myConnection.connect("rtmp:/myApp");

// Create the net stream. This example assumes that the stream is an audio-only
// stream for which we don't want to control the volume or panning, so we don't need
// to attach any audio or video.
subscribe_ns = new NetStream(myConnection);

// Create the response object.
myResponse = new Object(  );
myResponse.onResult = function (result) {

  // Assign the stream length to a variable on _root.
  _root.streamLength = result;

  // Begin the playback of the stream.
  _root.subscribe_ns.play("myStreamName");

  // Use an interval to call updateScroll(  ) to continually update the scroll position
  // so that it corresponds to the stream position.
  setInterval(_root, "updateScroll", 100);
};

// Call the server-side getStreamLength(  ) method. We're assuming you created this
// already in your main.asc file (or other loaded .asc).
myConnection.call("getStreamLength", myResponse, "myStreamName");

// Create an isMouseDown variable, and toggle its value depending on the mouse state.
// We use this to determine whether the user is scrolling or if the scrollbar is
// being updated by the sound playback progress.
_root.onMouseDown = function (  ) {
  _root.isMouseDown = true;
};
_root.onMouseUp = function (  ) {
  _root.isMouseDown = false;
};

// Create a callback function for the scrollbar.
function onScroll (sb) {
  // Perform the enclosed actions only if the user is scrolling, not if the scrollbar
  // position is being updated due to the progress of sound playback.
  if (_root.isMouseDown && scrollBar_sb.hitTest(_root._xmouse, _root._ymouse)) {

    // Get the current scroll position of the scrollbar (from 0 to 100).
    var percent = sb.getScrollPosition(  );

    // Calculate the seconds value that correspond to the percentage based on the
    // total stream length.
    var seconds = percent * streamLength / 100;

    // Seek to the appropriate point in the stream.
    subscribe_ns.seek(seconds);
  }
}

// This function updates the position of the scrollbar based on the current playback 
// position of the stream.
function updateScroll (  ) {
  if (!_root.isMouseDown && !scrollBar_sb.hitTest(_root._xmouse, _root._ymouse)) {
    var position = subscribe_ns.duration / streamLength * 100;
    scrollBar_sb.setScrollPosition(position);
  }
}

// Set the scrollbar properties and assign the change handler callback function. This
// example assumes that you have created a 
scrollbar instance on the Stage with a
// name of scrollBar_sb.
scrollBar_sb.setScrollProperties(10, 0, 100);
scrollBar_sb.setChangeHandler("onScroll");

14.13.4 See Also

Recipe 14.12, Recipe 14.14, and Recipe 14.16

    [ Team LiB ] Previous Section Next Section