...
Version | Author | Datum | Bemerkungen |
---|---|---|---|
0.1 | 23.05.2005 | Christopher Wirtz | initial |
0.5 | 26.05.2005 | Christopher Wirtz | Changes |
1.0 | 02.06.2005 | Christopher Wirtz | Release |
1.1 | 12.03.2007 | Christopher Wirtz | Flash added |
1.2 | 06.07.2009 | Christopher Wirtz | Review/Changes |
1.3 | 14.07.2009 | Christopher Wirtz | Added Example to set the „duration“ manually in ActionScript |
1.4 | 29.06.2010 | Christopher Wirtz | Unload delay |
1.5 | 02.11.2010 | Frank Kammann | Add Example using a NetStreamAdapter, streaming segments and parallel streams |
1.6 | 14.03.2011 | Frank Kammann | Description of the general operation (API) and information on the security settings for Flash |
Inhaltsverzeichnis
Table of Contents |
---|
Einleitung
Ob Nachrichtensendungen, Produkt-Präsentationen oder Online-Radioprogramme – alle setzen mittlerweile Audio- und Video-Streams als Kommunikationsmittel ein.
...
Das folgende Diagramm zeigt die Architektur der API:
Gliffy | ||||
---|---|---|---|---|
|
Info |
---|
Die Einfachheit der API und des Konzeptes führt zu den folgenden Features:
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
// 1. Instantiiere das API-Objekt
var sensors:SpringStreams = new SpringStreams("angebotsname");
// 2. Ein Description-Objekt für den Streaming-Content anlegen.
var desc:Object = {
"stream":"videos/mystream",
"duration":600, // in Sekunden
"sx":video.width,
"sy":video.height
};
// 3. Das Content-Objekt zur Verfügung stellen
var content:Object = ...; // Irgendein Objekt, dass in der Lage ist die aktuelle Position in Sekunden zu liefern
// 4. Den Content mit dem Description-Objekt auf dem Sensor registieren.
var stream:Stream = sensors.track(content, desc);
|
...
zu 1: Instantiiere das API-Objekt
Der korrekte Angebotsname muß angegeben werden. Dieser Angebotsname wird vom Betreiber der Streaming-Lösung vergeben.
Code Block borderColor grey bgColor #eeeeee borderStyle solid lang javascript var sensors:SpringStreams = new SpringStreams("angebotsname");
- Eine Instanz des Objektes
SpringStreams
ist im Framework nur einmalig anzulegen. Ab da können ein oder mehrere Streams dertrack
-Methode zur Messung übergeben werden.
zu 2: Ein Description-Objekt für den Streaming-Content anlegen
Im Description-Objekt muss mindestens der Name des Streams angegeben werden.
Code Block borderColor grey bgColor #eeeeee borderStyle solid lang javascript var desc:Object = { "stream":"videos/mystream", "duration":600 // in Sekunden };
Mit dem Description-Objekt übergibt man der API nähere Informationen zum Streaming-Content. Hierbei sind folgende Variablen erlaubt bzw. werden vom Messsystem verstanden.
Variable
Optional
Beschreibung
stream
Nein
Der Names des Streams, der optimalerweise als Hierarchie übergeben wird. z.B.
path/to/stream/name
duration
Nein
Die Duration muss angegeben werden. Im Falle von Livestreams kann sie weggelassen werden oder wird mit dem Wert
0
geliefertct
Ja
Hier kann ein beliebiger Wert verwendet werden, der ein Aussage über den ContentType macht.
Beispielweise könnte der Wertad
angegeben werden, um den Stream als Werbung zu markieren.sx
Ja
Die Breite (width) des Streamfensters - sofern es sich um einen Film handelt.
Im Falle eines Radiostreams, können die Variablen weggelassen werden oder werden mit dem Wert0
geliefert.sy
Ja
Die Höhe (height) des Streamfensters - sofern es sich um einen Film handelt.
Im Falle eines Radiostreams, können die Variablen weggelassen werden oder werden mit dem Wert0
geliefert.desc
Ja
Hier kann eine Beschreibung des Streams hinterlegt werden.
zu 3: Das Content-Objekt zur Verfügung stellen
Die einzige Anforderung an dieses Objekt seitens der Streaming-API ist, dass es die Möglichkeit bietet die aktuelle Position auf einem Stream in Sekunden auslesen zu können. Je nach Programmiersprache sind hier ebenfalls softwaretechnische Lösungen denkbar, wie die Implementierung von Interfaces oder die Implementierung von Adapterklassen.
Code Block borderColor grey bgColor #eeeeee borderStyle solid lang javascript var content:Object = ...;
zu 4: Den Content mit dem Description-Objekt auf dem Sensor registieren.
Im nächsten Schritt der Streaming-Content und das Description-Objekt der API-Methode
track
übergeben werden. Ab diesem Zeitpunkt wird die aktuelle Position auf dem Stream getracked. An dieser Stelle ist es möglich mehrere Streams parallel zu messen, in dem jeder zusätzlich Streaming-Content mit dem zugehörigen Description-Objekt ebenfalls dertrack
-Methode übergeben wird.Code Block borderColor grey bgColor #eeeeee borderStyle solid lang javascript var stream:Stream = sensors.track(content, desc);
- Die Messung einzelner Streams kann jederzeit durch den Aufruf der Methode
Stream.stop()
abgebrochen werden.
...
Info | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Ein Intervall ist definiert als:
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
// System-Objekt
[{"sx":1280,
"sy":1024,
"pl":"FlashPlugin",
"plv":"WIN 10,0,45,2"
},
// Nutzungsinformationen
{"stream":"spring/teststream",
"dur":"600",
"sx":"400",
"sy":"300",
"uid":"267fgut",
"vt":356,
"pst":[[0,0,"kzog7e"],[22,378,"kzog7e"]]
}]
|
Beim Datentransport werden zwei Objekte übermittelt:
Das System-Objekt, dass Informationen enthält wie Bildschirmauflösung, Playername und Playerversion.
Variable
Optional?
Beschreibung
sx
Nein
Die Breite des Bildschirms in Pixel (width)
sy
Nein
Die Höhe des Bildschirms in Pixel (height)
pl
Nein
Der Name des Players
plv
Nein
Die Playerversion
Die Nutzungsinformationeneiner Messung
Variable
Optional?
Beschreibung
plv
Nein
Die Playerversion
stream
Nein
Der Name des Streams
dur
,duration
Nein, wenn es kein Livestream ist.
Die Länge des Streams in Sekunden
sx
Nein
Die Breite des Streamfensters in Pixel(width) oder den Wert
0
sy
Nein
Die Höhe des Streamfensters in Pixel(height) oder den Wert
0
uid
Nein
Die Unique Id des Nutzungsvorganges
vt
Nein
Die Viewtime in Sekunden. Die Viewtime wird gemessen ab dem Aufruf der Methode
SpringStreams.track(...)
pst
Nein
Die Playstates. Die Liste mit Sichtungsintervallen auf dem Stream.
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<script src=".../springstreams.js"></script>
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var myAdapter = {
"getMeta" : function(id) {
return {
"pl" :"own player",
"plv" :"version1",
"sx" : screen.width,
"sy" : screen.height
}
},
"getDuration" : function(id) {
return 0;
},
"getPosition" : function(id) {
return new Date().getTime() / 1000;
}
};
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
sensors.track(someObject, desc, myAdapter);
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
sensors.debug = function(v) {
window.status = " " + v;
}
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
function unload() {
sensors.unload();
}
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
function unload() {
sensors.unload();
// give time for submission
var start= new Date(); var now = null; do now = new Date();
while(now-start < 100);
}
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<body onunload="unload();">
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var stream = sensors.track(someObject, desc, myAdapter);
...
stream.stop();
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
sensors.track(rvplayer, description, sensors.RVStreamAdapter);
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<html>
<head>
<title>spring sensors</title>
<script src="springstreams.js"></script>
</head>
<body onunload="unload();">
<script type="text/javascript">
var sensors = new SpringStreams("test");
var adapter = {
"getMeta" : function() {
return {
"pl" :"own player",
"plv" :"version1",
"sx" : screen.width,
"sy" : screen.height
}
},
"getDuration" : function() {
return 1000;
},
"getPosition" : function() {
return new Date().getTime() / 1000;
}
};
var desc = {
"stream": "videos/teststream"
}
sensors.track("someid", desc, adapter);
// uncomment for debugging
// sensors.debug = function(v) {
// window.status = v;
// }
function unload() {
sensors.unload();
// give time for submission
var start= new Date(); var now = null; do now = new Date();
while(now-start < 100);
}
</script>
</body>
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<script src=".../springstreams.js"></script>
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var sensors = new SpringStreams("test");
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
sensors.track(wmplayer, {});
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var description = {
"stream": "videos/teststream"
"desc": "some additional description"
};
sensors.track(wmplayer, description);
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<html>
<head>
<title>spring sensors</title>
<script src="springstreams.js"></script>
</head>
<body onunload="unload();">
<SCRIPT type="text/javascript">
if(-1 != navigator.userAgent.indexOf("MSIE"))
{
document.write('<OBJECT id="wmplayer" width="435" height="326" CLASSID="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" type="application/x-ms-wmp">');
document.write(' <param name="URL" value="http://wstreaming.zdf.de/zdf/veryhigh/070912_iaa_mim.asx">');
document.write(' <param name="AutoStart" VALUE="1">');
document.write(' <param name="ShowStatusBar" VALUE="1">');
document.write('</object>');
}
else {
document.write('<OBJECT id="wmplayer" width="435" height="326" type="application/x-ms-wmp">');
document.write(' <param name="URL" value="http://wstreaming.zdf.de/zdf/veryhigh/070912_iaa_mim.asx">');
document.write(' <param name="AutoStart" VALUE="1">');
document.write(' <param name="ShowStatusBar" VALUE="1">');
document.write(' </object>');
}
</SCRIPT>
<script type="text/javascript">
// "test" is the name of the tracked website
var sensors = new SpringStreams("test");
// wmplayer is the id of the stream above
sensors.track(wmplayer, {"stream":"videos/teststream"});
// uncomment for debugging
//sensors.debug = function(v) {
// window.status = v;
//}
function unload() {
sensors.unload();
// give time for submission
var start= new Date(); var now = null; do now = new Date();
while(now-start < 100);
}
</script>
</body>
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var sensors:SpringStreams = new SpringStreams("test");
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var sensors:SpringStreams = new SpringStreams("test", true);
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
sensors.track(ns,{});
|
Dem gemessenen Objekt können weitere, beschreibende Informationen mitgegeben werden:
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var description:Object = {
"stream": "videos/teststream",
"desc": "some additional infos",
"sx": video.width,
"sy": video.heigth,
};
sensors.track(ns, description);
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
<body onunload="unload()">
...
function unload() {
FlexProject.SPRING_UNLOAD();
}
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
function unload() {
FlexProject.SPRING_UNLOAD();
// give time for submission
var start= new Date(); var now = null; do now = new Date();
while(now-start < 100);
}
|
...
Folgende Einstellungen sind vorzunehmen (siehe: ExternalInterface#addCallback())
Legen Sie in der HTML-Seite im object-Tag der SWF-Datei den folgenden Parameter fest:
Code Block borderColor grey bgColor #eeeeee borderStyle solid lang html <param name="allowScriptAccess" value="always" />
Fügen Sie in der SWF-Datei den folgenden ActionScript-Code ein:
Code Block borderColor grey bgColor #eeeeee borderStyle solid lang javascript flash.system.Security.allowDomain( sourceDomain )
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var nsClient:Object = {};
nsClient.onMetaData = ...
nsClient.onCuePoint = ...
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.play(streamlocation);
ns.client = nsClient;
video = new Video();
video.attachNetStream(ns);
addChild(video);
var tracker:SpringStreams = new SpringStreams("test");
tracker.track(ns,{"stream":"videos/teststream","sx":video.width,"sy":video.height});
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var nsClient:Object = {};
nsClient.onMetaData = ...
nsClient.onCuePoint = ...
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.play(streamlocation);
ns.client = nsClient;
video = new Video();
video.attachNetStream(ns);
addChild(video);
var tracker:SpringStreams = new SpringStreams("test");
var stream:Stream = tracker.track(ns,{"stream":"videos/teststream","sx":video.width,"sy":video.height});
stream.setDuration(600/*10 minutes*/);
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var net:NetConnection = new NetConnection();
net.connect(null);
var ns:NetStream = new NetStream(net);
var currentPosition:Number = ns.time;
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
package
{
import flash.media.SoundChannel;
import flash.net.NetConnection;
import flash.net.NetStream;
public class SoundNetStreamAdapter extends NetStream
{
private var channel:SoundChannel;
public function SoundNetStreamAdapter(net:NetConnection, c:SoundChannel)
{
super(net);
channel = c;
}
override public function get time():Number {
// return the position in seconds
return channel.position/1000;
}
}
}
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var tracker:SpringStreams = new SpringStreams("test");
var s:Sound = new Sound();
s.load(new URLRequest("file:///pathto/sound.mp3"));
var desc:Object = {
"stream":"sounds/sound.mp3",
"sx":0,"sy":0,
};
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new SoundNetStreamAdapter(nc, s.play());
var stream:Stream = tracker.track(ns, desc);
stream.setDuration(s.length/1000); // duration in seconds
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
var nsClient:Object = {};
nsClient.onMetaData = ...
nsClient.onCuePoint = ...
nc = new NetConnection();
nc.connect(null);
ns = new NetStream(nc);
ns.play(streamlocation);
ns.client = nsClient;
video = new Video();
video.attachNetStream(ns);
addChild(video);
// 20:00 - 20:15 Tagesschau
// 20:15 - 21:00 PlusMinus
var tracker:SpringStreams = new SpringStreams("test");
// 20:00
var stream:Stream = tracker.track(ns,{"stream":"livestreams/ard/Tagesschau","sx":video.width,"sy":video.height});
// 20:15
stream.stop();
stream = tracker.track(ns,{"stream":"livestreams/ard/PlusMinus","sx":video.width,"sy":video.height});
|
...
Code Block | ||||||||
---|---|---|---|---|---|---|---|---|
| ||||||||
...
ns1 = new NetStream(...);
...
ns2 = new NetStream(...);
...
var tracker:SpringStreams = new SpringStreams("test");
var stream1:Stream = tracker.track(ns1,{"stream":"streams/stream1","sx":video.width,"sy":video.height});
var stream2:Stream = tracker.track(ns2,{"stream":"streams/stream2","sx":video.width,"sy":video.height});
|