Go Back   OpenLaszlo Developers Forums > OpenLaszlo Showcase > Show us your code!

Show us your code! Want to show your cool OpenLaszlo components, libraries and code hacks apps to the world? Submit your best code here. We'll showcase the best of the best on the OpenLaszlo site and in the OpenLaszlo project blog, and may even add them to a future release for all to use!

 
 
Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
  #1  
Old 11-10-2011, 08:28 AM
kmeixner kmeixner is offline
Senior Community Member
 
Join Date: Dec 2006
Location: Toronto, Ontario, Canada
Posts: 636
kmeixner is on a distinguished road
Standard media interface across platforms

Here are some classes I created so that I can have a standard media interface and behaviour across different runtimes and media types:

Code:
<switch>
  <when property="$dhtml">
    <!-- Not-yet-released OpenLaszlo html5video and html5audio classes -->
    <include href="/usr/local/lps-5.0.x/Server/lps-5.0.x/lps/components/av/html5/library.lzx" />	    
  </when>
</switch>
  
<class name="sarbasemediacontainer" extends="view">

  <!--- @param text src: The URL to load the media from -->
  <attribute name="src" type="text" />
  
  <!--- @keywords private -->
  <!--- @param boolean autoplay: (private, for future use only) if true autoplay the video/audio -->
  <attribute name="autoplay" type="boolean" value="false" />  

</class>

<class name="sarvideocontainer" extends="sarbasemediacontainer">

  <!--- 
  @param boolean use_videoview: (default: false) if true use <videoview> 
                                container for the video rather than <view>.
								(Applies to Flash mode only)
  -->
  <attribute name="use_videoview" type="boolean" value="false" />

  <switch>
  
    <when property="$dhtml">
	
	  <!-- *** METHODS *** -->
	
      <method name="doPlay">
        this.vwMedia.play();
      </method>
  
      <method name="doPause">
        this.vwMedia.pause();
      </method>  
  
      <method name="doStop">
	    // KM NOTE: HTML5 video/audio has no stop() so need this workaround:
        this.vwMedia.pause();
        this.vwMedia.setAttribute('currentTime', 0);	
      </method>  

      <method name="seekToMs" args="nMilliseconds, blnPauseMedia, nFrameInterval">
	    if (!blnPauseMedia){
		  this.vwMedia.setAttribute('currentTime', nMilliseconds);		  
		}
		else {
		  this.vwMedia.pause();
		  this.vwMedia.setAttribute('currentTime', nMilliseconds);		  
		}
      </method>			  
	
	  <!-- *** EVENTS *** -->	  
	  
	  <handler name="onsrc" args="strSrc">
	    this.vwMedia.unload(); // TBD: Does this work with html5 elements?
	    this.vwMedia.setAttribute('src', strSrc);
	  </handler>		
	
      <!-- *** COMPONENTS *** -->	 	
	  
	  <html5videoview name="vwMedia" 
	                  controls="false"
                      stretches="both"	  
	                  width="${parent.width}" 
					  height="${parent.height}" 
					  autoplay="${parent.autoplay}"					  
	  />
	  
	</when>
	
	<otherwise>
	
	  <state name="stSWFVideo" applied="${!classroot.use_videoview}">
	  
	  <!-- *** METHODS *** -->
	
      <method name="doPlay">
        this.vwMedia.play();
      </method>
  
      <method name="doPause">
        this.vwMedia.stop();
      </method>  
  
      <method name="doStop">
        this.vwMedia.stop(0, false);
      </method>  	
	  
      <method name="seekToMs" args="nMilliseconds, blnPauseMedia, nFrameInterval">
	    if (!blnPauseMedia){
		  this.vwMedia.play(Math.floor(nMilliseconds/nFrameInterval));
		}
		else {
		  this.vwMedia.stop(Math.floor(nMilliseconds/nFrameInterval));		
		}
      </method>	 	  
	
      <!-- *** EVENTS *** -->	  
  
      <handler name="onsrc" args="strSrc">
	      this.vwMedia.unload(); // workaround: prevent retention of media when strSrc set to ''		  
	      this.vwMedia.setSource(strSrc);
      </handler> 

      <!-- *** COMPONENTS *** -->	  

      <view name="vwMedia" 
            stretches="both"
		    width="${parent.width}"
		    height="${parent.height}"		
	  >
		
        <!-- Method 1: audio plays for a couple seconds then pauses -->				
		
		<handler name="onresource">
		  if (!parent.autoplay)
		    parent.doStop();
		</handler>
		
		<!-- Method 2: does not seem to work for video but no harm in including just in case -->
		
	    <!--- @keywords private -->
	    <!--- @param boolean iscompletedloading: this changes only when loadratio becomes 1 or not 1 -->		
	    <attribute name="iscompletedloading" type="boolean" value="false" />		
	  
	    <handler name="onloadratio" args="nLoadRatio">
		<![CDATA[
		
		  // Workaround for OpenLaszlo problem where nLoadRatio will be 
		  // called a "bazillion" times with nLoadRatio=1, trigger 
		  // oniscompletedloading change only once when needed
		
		  if (nLoadRatio == 1 && !this.iscompletedloading){
		    this.setAttribute('iscompletedloading', true);
		  }
		  else if (this.iscompletedloading){
		    this.setAttribute('iscompletedloading', false);		  
		  }
		    
	    ]]>
		</handler>
		<!-- OL problem Workaround: This will only fire when nLoadRatio becomes 1 or not 1 -->
		<handler name="oniscompletedloading" args="blnIsCompletedLoading">
		
		  if (!blnIsCompletedLoading)
		    return;
			
		  if (!parent.autoplay){
		    parent.doStop();
		  }
		  else {
		    parent.doPlay();		  
		  }
		
		</handler>	  
	  
	  </view>
	  </state>	

      <state name="stMP4orFLV" applied="${classroot.use_videoview}">
	  <!-- *** METHODS *** -->
	
      <method name="doPlay">
        this.vwMedia.stream.play();
      </method>
  
      <method name="doPause">
        this.vwMedia.stream.pause(true); // true forces stop playback
      </method>  
  
      <method name="doStop">
	    //this.vwMedia.stream.stop(); // Note: broken in OL 4.9.0, use pause(), seek(0) workaround
        this.vwMedia.stream.pause(true); // true forces stop playback
        this.vwMedia.stream.seek(0);		
      </method>  	
	  
      <method name="seekToMs" args="nMilliseconds, blnPauseMedia, nFrameInterval">
	    if (!blnPauseMedia){
		  this.vwMedia.stream.seek(nMilliseconds/1000);
		}
		else {
		  this.vwMedia.stream.pause(true); // true forces stop playback
		  this.vwMedia.stream.seek(nMilliseconds/1000);
		}
      </method>	 	  
	
      <!-- *** EVENTS *** -->	  
  
      <handler name="onsrc" args="strSrc">
	      this.vwMedia.unload(); // workaround: prevent retention of media when strSrc set to ''		  
	      this.vwMedia.setAttribute('url', strSrc);
      </handler> 

      <!-- *** COMPONENTS *** -->	  

      <videoview name="vwMedia" type="http"
                 stretches="both"
		         width="${parent.width}"
		         height="${parent.height}"		
				 autoplay="${parent.autoplay}"
	  >	  
	  </videoview>
	  </state>
         
	</otherwise>	
	
  </switch>
  
  <method name="destroy">
    this.vwMedia.unload();
	super.destroy();
  </method>

</class>

<class name="saraudiocontainer" extends="sarbasemediacontainer"
       width="0"
	   height="0"
>

  <switch>
  
    <when property="$dhtml">
	
	  <!-- *** METHODS *** -->
	
      <method name="doPlay">
        this.vwMedia.play();
      </method>
  
      <method name="doPause">
        this.vwMedia.pause();
      </method>  
  
      <method name="doStop">
	    // KM NOTE: HTML5 video/audio has no stop() so need this workaround:
        this.vwMedia.pause();
        this.vwMedia.setAttribute('currentTime', 0);	
      </method>  	
	  
      <method name="seekToMs" args="nMilliseconds, blnPauseMedia, nFrameInterval">
	    if (!blnPauseMedia){
		  this.vwMedia.setAttribute('currentTime', nMilliseconds);		  
		}
		else {
		  this.vwMedia.pause();
		  this.vwMedia.setAttribute('currentTime', nMilliseconds);		  
		}
      </method>		  
	
	  <!-- *** EVENTS *** -->	  
	  
	  <handler name="onsrc" args="strSrc">
	    this.vwMedia.unload(); // TBD: Does this work with html5 elements?	  
 	    this.vwMedia.setAttribute('src', strSrc);
	  </handler>	
	
      <!-- *** COMPONENTS *** -->	 	
	  
	  <html5audioview name="vwMedia" 
	                  controls="false"	  
	                  width="0" 
					  height="0" 
					  autoplay="${parent.autoplay}"
	  />	
	
	</when>
	
	<otherwise>
	
	  <!-- *** METHODS *** -->
	
      <method name="doPlay">
        this.vwMedia.play();
      </method>
  
      <method name="doPause">
        this.vwMedia.stop();
      </method>  
  
      <method name="doStop">
        this.vwMedia.stop(0, false);
      </method>  
	  
      <method name="seekToMs" args="nMilliseconds, blnPauseMedia, nFrameInterval">
	    // KM NOTE: Even though this is an audio file, using fps works in OpenLaszlo
	    if (!blnPauseMedia){
		  this.vwMedia.play(Math.floor(nMilliseconds/nFrameInterval));
		}
		else {
		  this.vwMedia.stop(Math.floor(nMilliseconds/nFrameInterval));		
		}
      </method>			  
	  
	  <!-- *** EVENTS *** -->	  
	  
	  <handler name="onsrc" args="strSrc">
	    this.vwMedia.unload(); // workaround: prevent retention of media when strSrc set to ''
		this.vwMedia.setSource(strSrc);
	  </handler>	  
	  
	  <!-- *** COMPONENTS *** -->	  	  

      <view name="vwMedia">
	  
        <!-- Method 1: audio plays for a couple seconds then pauses -->			  
	  
		<!--handler name="onresource">
		  if (!parent.autoplay)
		    parent.doStop();
		</handler-->	

        <!-- Method 2: results in audio silent from the start -->		
	  
	    <!--- @keywords private -->
	    <!--- @param boolean iscompletedloading: this changes only when loadratio becomes 1 or not 1 -->		
	    <attribute name="iscompletedloading" type="boolean" value="false" />
	  
	    <handler name="onloadratio" args="nLoadRatio">
		<![CDATA[
		
		  // Workaround for OpenLaszlo problem where nLoadRatio will be 
		  // called a "bazillion" times with nLoadRatio=1, trigger 
		  // oniscompletedloading change only once when needed
		
		  if (nLoadRatio == 1 && !this.iscompletedloading){
		    this.setAttribute('iscompletedloading', true);
		  }
		  else if (this.iscompletedloading){
		    this.setAttribute('iscompletedloading', false);		  
		  }
		    
	    ]]>
		</handler>
		<!-- OL problem Workaround: This will only fire when nLoadRatio becomes 1 or not 1 -->
		<handler name="oniscompletedloading" args="blnIsCompletedLoading">
		
		  if (!blnIsCompletedLoading)
		    return;
			
		  if (!parent.autoplay){
		    parent.doStop();
		  }
		  else {
		    parent.doPlay();		  
		  }
		
		</handler>
	   
	  </view>
	
	</otherwise>	
  </switch>
  
  <method name="destroy">
    this.vwMedia.unload();
	super.destroy();
  </method>  

</class>

<class name="sarimagecontainer" extends="sarbasemediacontainer">

  <!-- *** METHODS *** -->

  <method name="doPlay">
    return; // do nothing for image
  </method>
  
  <method name="doPause">
    return; // do nothing for image
  </method>  
  
  <method name="doStop">
    return; // do nothing for image
  </method>  
  
  <method name="seekToMs" args="nMilliseconds, blnPauseMedia, nFrameInterval">
    return; // do nothing for image
  </method>
  
  <!-- *** EVENTS *** -->	  
  
  <handler name="onsrc" args="strSrc">
	this.vwMedia.unload(); // workaround: prevent retention of media when strSrc set to ''
    this.vwMedia.setSource(strSrc);
  </handler> 

  <!-- *** COMPONENTS *** -->	  

  <view name="vwMedia" 
        stretches="both"
		width="${parent.width}"
		height="${parent.height}"		
  />
  
  <method name="destroy">
    this.vwMedia.unload();
	super.destroy();
  </method>  
  
</class>

<class name="sarmediacontainer" extends="view">

  <!-- *** ATTRIBUTES *** -->

  <!--- @param text mediatype: image|audio|video -->
  <attribute name="mediatype" type="text" required="true" />
  
  <!--- @param text src: the media url -->
  <attribute name="src" type="text" required="true" />  
  
  <!--- 
  @param boolean use_videoview: (default: false) if true use <videoview> 
                                container for the video rather than <view>.
								(Applies to Flash mode only, set to true for 
								MP4 or FLV playback in Flash mode)
  -->
  <attribute name="use_videoview" type="boolean" value="false" />  

  <!--- 
  @param text fpstype: (optional)(Default: ntsc) The type of fps system. 
                       ntsc|pal for North American, European respectfully
  -->
  <attribute name="fpstype" type="text" value="ntsc" />  
  
  <state name="stFpsNtsc" applied="$once{classroot.fpstype == 'ntsc'}">
  
    <!--- @keywords private -->
    <!--- @param number fps: Frames Per Second -->  
    <attribute name="fps" type="number" value="$once{30/1001}" />  
	
    <!--- @keywords private -->
    <!--- @param number frameinterval: Time between frames in milliseconds -->  
    <attribute name="frameinterval" type="number" value="$once{1001/30}" />    
	
  </state>
  
  <state name="stFpsPal" applied="$once{classroot.fpstype == 'pal'}">  
  
    <!--- @keywords private -->
    <!--- @param number fps: Frames Per Second -->    
    <attribute name="fps" type="number" value="25" />  
	
    <!--- @keywords private -->
    <!--- @param number frameinterval: Time between frames in milliseconds -->    
    <attribute name="frameinterval" type="number" value="40" />      
	
  </state>
  
  <!--- @param boolean autoplay: if true start playing the media immediately -->
  <attribute name="autoplay" type="boolean" value="false" />    
  
  <!-- *** METHODS *** -->

  <method name="doPlay">
    this.vwDisplay.doPlay();
  </method>
  
  <method name="doPause">
    this.vwDisplay.doPause();
  </method>  
  
  <method name="doStop">
    this.vwDisplay.doStop();
  </method>    
  
  <method name="seekToMs" args="nMilliseconds, blnPauseMedia=false">
    this.vwDisplay.seekToMs(nMilliseconds, blnPauseMedia, this.frameinterval);
  </method>
  
  <!-- *** EVENTS *** -->
  
  <handler name="oninit">
    this.vwDisplay.setAttribute('src', this.src);
  </handler>  
  
  <handler name="onsrc" args="strSrc">
  
    if (!this['vwDisplay'])
	  return; // not initialized yet
	  
    this.vwDisplay.setAttribute('src', strSrc);
  </handler>
  
  <!-- *** COMPONENTS *** -->
  
  <state name="stImage" applied="${classroot.mediatype == 'image'}">
    <sarimagecontainer name="vwDisplay" 
	                   width="${parent.width}" 
					   height="${parent.height}" 
    />
  </state>
  
  <state name="stAudio" applied="${classroot.mediatype == 'audio'}">
    <saraudiocontainer name="vwDisplay" 
					   autoplay="${parent.autoplay}"	
	                   width="0" 
					   height="0" 
    />	
  </state>  
  
  <state name="stVideo" applied="${classroot.mediatype == 'video'}">
    <sarvideocontainer name="vwDisplay"
	                   use_videoview="${parent.use_videoview}"
					   autoplay="${parent.autoplay}"	
	                   width="${parent.width}" 
					   height="${parent.height}" 
    />	
  </state>  

</class>
This is tested and works under OpenLaszlo 4.9.0 assuming you include the following library from the nightly build:

Code:
<include href="/usr/local/lps-5.0.x/Server/lps-5.0.x/lps/components/av/html5/library.lzx" />
I thought it might be useful to others.

Kevin
__________________
Me: Stack Overflow | Assembla | Twitter | LinkedIn | www.kevinmeixner.com
Company: Web | Facebook | Twitter

Last edited by kmeixner; 11-10-2011 at 10:04 AM. Reason: Added <sarmediacontainer> class that can handle video, audio or image in one class
Reply With Quote
 

Bookmarks

Tags
audio, html5, media, video

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 06:11 AM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.