Skip to main content
June 13, 2011
Question

Auto-archiving streams with H.264 video

  • June 13, 2011
  • 1 reply
  • 950 views

My CDN is running FMS, and my customers and I stream a lot of live traffic through it. We've got FMS configured to auto-archive our live streams, but that only works for stream using VP6 video. When I look at the archived files captured from H.264 streams I get audio but no video.

Is it possible to get FMS to autoarchive H.264 streams? Or is this planned for a future release of FMS?

    This topic has been closed for replies.

    1 reply

    Nikhil_Kalyan
    Participating Frequently
    June 13, 2011

    Hi,

    Thanks for using FMS.

    It is possible to archive H264 video.

    I hope you must be using server side scripting to archive on the server. If you can see that, the record would have something like this.

    s = stream.get("filename.flv");

    s.record();

    So, for H264, you need the mp4 format, which you can provide as :

    s = stream.get("mp4:filename.mp4");

    s.record();

    Note that, mp4: prefix is the mandatory item here, the extension is not, you can either give mp4/f4v or no extension.


    If you are not using the server side script, please let me know how are you handling the recording, i can help there too. But the basic point remains the same, you just need to add mp4: prefix and make sure you are recording mp4/f4v files .

    Please let us know if it helped. Thank you !

    June 15, 2011

    Yes, that does help, thanks!

    We do indeed have a script running to do our auto-archving. It currently doesn't recognize h.264, but with the info you provided I should be able to modify it to do so.

    What we are currently running is:

     
    /*                                        
    * (C) Copyright 2007 Adobe Systems Incorporated. All Rights Reserved.
    *                                                                 
    * NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the
    * terms of the Adobe license agreement accompanying it.  If you have received this file from a
    * source other than Adobe, then your use, modification, or distribution of it requires the prior
    * written permission of Adobe.                                                                
    * THIS CODE AND INFORMATION IS PROVIDED "AS-IS" WITHOUT WARRANTY OF                           
    * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO                         
    * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A                              
    * PARTICULAR PURPOSE.                                                                         
    *                                                                                             
    *  THIS CODE IS NOT SUPPORTED BY Adobe Systems Incorporated.                                  
    *                                                                                             
    */                                                                                            
                                                                                                   
    /* Adobe Flash Functions */                                                                    

    /* Load webservices.asc */
    load("webservices/WebServices.asc");
    trace(" * Loaded webservices/WebServices.asc");

    trace(" * Started Application");

    application.onConnect = function( client ) {
            /* Connection has started */     
            client.getStreamLength = function( streamName ) {
                    trace(" * Length => " + Stream.length( streamName ));
                    return Stream.length( streamName );               
            }                                                         
            trace(" * Camera Connected");                             
            application.acceptConnection( client );                   
    }                                                                 

    application.onPublish = function (p_c, p_stream) {
            /* Publishing has started */           
            trace(" * p_c => " + p_c);             
            trace(" * p_stream => " + p_stream);   
            trace(" * Publishing started for stream " + p_stream.name);
            p_stream.archiveStart();                                
    }                                                               

    application.onUnpublish = function (p_c, p_stream){
            /* Publishing has stopped */            
            trace(" * Publishing stopped for stream " + p_stream.name);
            p_stream.archive();                                     
    }                                                               

    /* Our Custom Functions */

    /* Last Modified Tue Dec 1 2:55 pm */

    trace(" * Loading Custom Functions ... ");

    Date.prototype.unixTime = function () {
            /* Create and returl unix timestamp */
            trace(" * Getting UNIX Timestamp ... ");
            return Math.round(this.getTime() / 1000);
    }                                             

    Stream.prototype.archiveStart = function() {
            /* Start archiving stream */     
            this.record(); // start recording live stream
            trace(" * Recording started for stream");          
            this.startTime  = (new Date()).unixTime();
            // attach start time in unix time to object
    }                                                                                                                                                                                                                                       

    Stream.prototype.archive = function() {
            trace(" * Function => Stream.prototype.archive");
            this.record(false);
            // stop recording live stream                                                                                                                                                                                                              
            trace(" * Setting this.record to false");                                                                                                                                                                                         
            f = "/streams/_definst_/" + this.name + ".flv";
            // current name of file that was recorded                                                                                    
            trace(" * f => " + f);                                                                                                                                                                                                            
            src             = new File(f); // create a new file object of for sourse                                                                                                                                                                                                  

            if(src.exists){
                    /* src file exists */
                    trace(" * Src for " + f + " exists");

                    /* Create new unique name for recorded stream */
                    f1 = '/streams/_definst_/live_event_archives/auto_archive_' + this.name + '_'  + this.startTime + ".flv";
                    trace (" * New file name => " + f1);

                    /* Copy src file to new file */
                    try{
                            src.copyTo(f1);
                            trace(" * Copied src to " + f1);
                    }
                    catch(error){
                            trace(" * ERROR copying src to " + f1 + ": " + error.message);
                    }

                    /* Remove src file */
                    try{
                            src.remove(); // remove source file
                            trace(" * Removed src");
                    }
                    catch(error){
                            trace(" * ERROR deleting file: " + error.message);
                    }

                    /* Make web service request to vod server */
                    trace(" * Preparing to send to vod server ... ");
                    this.sendToVOD(this.name,f1,this.startTime,new Date().unixTime());
            }
            else{
                    trace(" * ERROR! Src does not exist! " + src);
            }
    }

    Stream.prototype.sendToVOD = function(n,f,s,e) {
            trace(" * Preparing to submitting data to vod server ... ");
            trace(" * n => " + n );
            trace(" * f => " + f );
            trace(" * s => " + s );
            trace(" * e => " + e );

            /* URL for web service call */
            var cst_url = "http://cst.{OUR DOMAIN}.net/gateway/point/?name=" + n + '&file=' + f + '&start=' + s + '&end=' + e;
            trace(" * URL => " + cst_url);

            /* Init new webservice url call */
            var web = new WebService(cst_url);

            /* Make web service request */
            web.onLoad = function(wsdl){
                    trace(" * Connected to vod web service");
            }
            web.onFault = function (wsdl){
                    trace(" * Could not connect to vod web service!");
            }
    }


    So, I will see if I can't modify it to decide whether it need to do mp4 or flv, and see if that helps.