Flash Media Server - DVR

Ein neues Feature des Flash Media Servers 3.5 ist das Digital Video Recording (DVR). Landläufig auch als Timeshift (zeitversetztes Fernsehen) bekannt, kann man damit einen Livestream pausieren und darin spulen, obwohl die Liveausstrahlung noch läuft.

Der Livestream wird also auf dem Server abgespeichert. Der Benutzer kann dadurch gleichzeitig den Livestream und auch auf das bereits gesendete Material zurückgreifen.

Ein weiterer Vorteil besteht in der schnellen Verfügbarkeit des Livestreams als Video-on-Demand:

A unique opportunity for this approach is making the video-on-demand (VOD) content available quickly following the live event without the time-consuming requirement of sending, encoding, and uploading it. The recorded content can simply be made available as VOD content.

Voraussetzungen für DVR

Wie beim Dynamic Streaming sind auch für das DVR keine besonderen Vorbereitungen auf dem Server oder beim Client zu treffen. Zum Publizieren muss lediglich der FMS 3.5 verwendet werden, allerdings in der teueren Version (Flash Media Interactive Server, siehe auch Erklärung der Versionen).

Zum Anschauen kann jeder beliebiger Flash Player/AIR verwendet werden (natürlich abhängig vom verwendeten Videocodec).

Demo

Hier ein kurzes Video, das die DVR-Funktionalität in Aktion zeigt. Links ist der Livestream, der eingespeist wird (im Beispiel einfach eine Webcam). Die rechte Hälfte entspricht dem Betrachter. Anfänglich ist der Livestream zu sehen, der naturgemäß einige Sekunden zeitversetzt ist. Gegen Ende wird über die Buttons darin gespult.

Get Adobe Flash player

Codebeispiel für DVR

Zuerst wird eine Verbindung zum FMS aufgebaut (Funktion onCreationComplete). Ist der Verbindungsaufbau erfolgreich (_onNetStatus), wird die Webcam als Livestream zum FMS publiziert (publishVideo). Gleichzeitig wird der Livestream in einem zweiten Videobild rechts angezeigt (receiveVideo).

XML:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. :Application xmlns:mx="http://www.adobe.com/2006/mxml"  creationComplete="onCreationComplete()" backgroundColor="#ffffff">
  3.     :Script>
  4.        
  5.             private var nc:NetConnection;
  6.             private var nsPublish:NetStream;
  7.             private var nsReceive:NetStream;           
  8.  
  9.        
  10.             private function onCreationComplete():void  {  
  11.                
  12.                 // Verbindung zum FMS aufbauen 
  13.                 nc = new NetConnection();
  14.                 nc.addEventListener( NetStatusEvent.NET_STATUS, _onNetStatus);
  15.                 nc.connect( "rtmp://192.168.2.108/dvr/" );
  16.             } 
  17.                        
  18.            
  19.         private function publishVideo():void {
  20.                
  21.                 // NetStream mit Kamera verbinden
  22.                 var myCam:Camera = Camera.getCamera();
  23.                 myCam.setMode(640, 480, 25);
  24.                 nsPublish = new NetStream(nc);
  25.                 nsPublish.attachCamera(myCam);
  26.                 nsPublish.attachAudio( Microphone.getMicrophone() );
  27.                
  28.                 // Client für Metadaten,etc, festlegen
  29.                 nsPublish.client = this;               
  30.                
  31.                 // Video publizieren
  32.                 nsPublish.publish( "myDVR", "record");
  33.  
  34.                 var myVidDisplay1:Video = new Video();
  35.                 myVidDisplay1.attachCamera(myCam);
  36.                 myVidContainer1.addChild (myVidDisplay1);           
  37.         }
  38.        
  39.         private function receiveVideo():void { 
  40.            
  41.                 // NetStream zum Empfangen         
  42.                 nsReceive = new NetStream(nc);
  43.                 nsReceive.client = this;
  44.                 nsReceive.play("myDVR",  0, -1);
  45.  
  46.  
  47.                 var myVidDisplay2:Video = new Video();
  48.                 myVidDisplay2.attachNetStream(nsReceive);
  49.                 myVidContainer2.addChild(myVidDisplay2);
  50.         }
  51.                    
  52.         private function _onNetStatus( p_evt:NetStatusEvent ):void {   
  53.             if (p_evt.info.code == "NetConnection.Connect.Success") {
  54.                     publishVideo();
  55.                     receiveVideo();
  56.                     trace ("success");
  57.             }
  58.         }              
  59.            
  60.         public function onMetaData(e:Object):void {}
  61.        
  62.         public function onPlayStatus(e:Object):void {}     
  63.            
  64.         ]]>
  65.     :Script>
  66.     :HBox>      
  67.         :UIComponent id="myVidContainer1"  width="320" height="280"/>
  68.         :VBox>
  69.             :UIComponent id="myVidContainer2" width="320" height="280"/>
  70.             :HBox>
  71.                 :Button label="- 5s" click="nsReceive.seek(nsReceive.time - 5)"/>
  72.                 :Button label="+ 5s" click="nsReceive.seek(nsReceive.time + 5)"/>       
  73.             :HBox>
  74.         :VBox>
  75.    
  76.     :HBox>   
  77. :Application>

Link: Understanding live DVR (Adobe Developer Connection)