DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations
Building Scalable Real-Time Apps with AstraDB and Vaadin
Register Now

Trending

  • Cypress Tutorial: A Comprehensive Guide With Examples and Best Practices
  • A Data-Driven Approach to Application Modernization
  • What Is React? A Complete Guide
  • Auto-Scaling Kinesis Data Streams Applications on Kubernetes

Trending

  • Cypress Tutorial: A Comprehensive Guide With Examples and Best Practices
  • A Data-Driven Approach to Application Modernization
  • What Is React? A Complete Guide
  • Auto-Scaling Kinesis Data Streams Applications on Kubernetes
  1. DZone
  2. Coding
  3. Languages
  4. Pushing HTML5 Video Content over ColdFusion WebSockets

Pushing HTML5 Video Content over ColdFusion WebSockets

Sagar Ganatra user avatar by
Sagar Ganatra
·
Apr. 18, 12 · Interview
Like (0)
Save
Tweet
Share
5.94K Views

Join the DZone community and get the full member experience.

Join For Free

I’ve been playing with the WebSocket feature introduced in ColdFusion 10 for some time now. I was trying out pushing images over a ColdFusion WebSocket channel and it worked just fine. But this time I wanted to put WebSockets to test and wanted to push large data at regular intervals. I thought maybe I can push video data over WebSockets and it turned out that there is no direct way to stream video data to many clients. I came across the function - drawImage that can be used to draw an Image or Video on a HTML5 Canvas. Once an image is drawn on the Canvas, it’s base64 encoded data can be obtained by calling the toDataURL function on the Canvas object.  This data can then be transferred over a ColdFusion WebSocket to all subscribers who can then use this  data to draw the image(video frame) on a Canvas.

Here’s the demo video:

Unable to display content. Adobe Flash is required.

Please note, I’m not transferring the audio track present in the Video and I’m still trying to figure how that can be achieved.

Here’s the Publisher code:

<!DOCTYPE html> 
<html>
    <body> 
    <cfwebsocket name="socket" onmessage="messageHandler"> 
    <video id="videoElement" controls muted> 
        <source src="windowsill.webm" type="video/webm"> </video>
    <br> 
    <canvas id="canvasElement" style="border: solid 1px;"> 
    </canvas> 
    
    <script type="text/javascript"> 
      var context,canvasElement,videoElement, previous, current; 

      //message handler for CF WebSocket 
      messageHandler = function(msg){ 
      } 

      //function to call once the DOM content has been loaded 
      document.addEventListener('DOMContentLoaded', function(){ 
        videoElement = document.getElementById('videoElement'); 
        canvasElement = document.getElementById('canvasElement'); 
        context = canvasElement.getContext('2d'); 
      }); 
        
      //function to call once the videos meta data is available 
      document.getElementById('videoElement').addEventListener('loadedmetadata', function(){ 
         
         //set the canvas width and height to videos width and height 
          canvasElement.width = videoElement.videoWidth; 
          canvasElement.height = videoElement.videoHeight; 
          
          //event listener when the video is played 
          videoElement.addEventListener('play', function(){
            //call the draw function 
            draw(this, videoElement.videoWidth, videoElement.videoHeight); 

          }); 
        }); 

        //function to draw the video frame on a temporary canvas at 20fps 
        function draw(video, width, height){ 
          
          //if the video has been paused or ended return false 
          if (video.paused || video.ended) return false; 
          
          //draw the current video frame onto a canvas 
          context.drawImage(video, 0, 0, width, height); 
          
          //get base64 encoded data from Canvas 
          current = canvasElement.toDataURL("image/png"); 

          //just in case if the previous frame is same as current 
          if (previous != current) {
           
           //transfer the base64 encode image over a WebSocket 
           socket.publish("myChannel", current); 

         } 

          previous = current; //draw the video frame on the canvas at 20fps by calling the draw function every 50ms setTimeout(draw, 50, video, width, height); 
        } 
      </script> 
    </body>
</html>

As you can see from the above code, once you start playing the video the draw function is called. Here I've drawn the video on a Canvas using the drawImage function and then used the function toDataURL to get the base64 encoded data of the image. This is then transferred over a ColdFusion WebSocket channel (‘myChannel’). I’m calling this function (‘draw’) every 50ms to draw the current video frame on the canvas (to achieve 20fps) and transfer the image over a WebSocket.

The client\subscriber on receiving the data, draws  the image (video frame) on a canvas. Here’s the subscriber code:

<!DOCTYPE HTML> 
<html> 
  <body> 
      <cfwebsocket name="socket" onmessage="messageHandler" onopen="openHandler"> 
      <canvas id="canvasElement" style="border: solid 1px;" width="426" height="240"> 
      </canvas> 
  </body> 
  <script type="text/javascript"> 
    var canvas, context, count = 0, flag = false; 
    var newImage = new Image(); 
    document.addEventListener('DOMContentLoaded', function(){ 
      canvas = document.getElementById('canvasElement'); 
      context = canvas.getContext('2d'); 
    }); 

    function openHandler(){ 
      
      //subscribe to the CF WebSocket channel 
      socket.subscribe("myChannel", {}, dataHandler); 
    } 
    
    function messageHandler(msg){ 
    } 

    //function that receives the data from the WebSocket channel 
    function dataHandler(msg){ 
      if (msg.type == 'data') { 
        
        //function to call when the image is loaded with base64 data 
        newImage.onload = function(){ 
          
          //draw the image on the canvas 
          context.drawImage(newImage, 0, 0); 
          
          //set the flags when the above function is complete 
          flag = true; count = 1; 

        } 

        //if ready to be drawn on the canvas 
        if (count == 0 || flag == true) { 
          flag = false; 

          //assign base64 data to the source of the image 
          newImage.src = msg.data; 

        } 
      } 
    } 
  </script> 
</html>

On the client side, once the data is received over the WebSocket it is assigned to the source of an Image object. The reason why I do this is because the drawImage function takes either an Image or a Video as it's first argument and doesn't allow base64 data. Once the Image is loaded, it is ready to be drawn on the canvas. This process continues until the video ends or the user pauses the video. 

HTML WebSocket

Published at DZone with permission of Sagar Ganatra, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Trending

  • Cypress Tutorial: A Comprehensive Guide With Examples and Best Practices
  • A Data-Driven Approach to Application Modernization
  • What Is React? A Complete Guide
  • Auto-Scaling Kinesis Data Streams Applications on Kubernetes

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com

Let's be friends: