Dieser Artikel wurde maschinell übersetzt.

IIS Smooth Streaming

Verbesserte Silverlight-Videofunktionen mit Kontextdaten

Jit Ghosh

Downloaden des Codebeispiels

Es gibt zwei Hauptanforderungen für eine Anzeige bei Ausfällen frei Erfahrung in Web-based, High Definition-digitale video Übermittlung aktivieren. Zunächst muss der video-Anbieter Bitraten hohe video Übermittlung über das Netzwerk zu unterstützen. Zweitens muss der Clientcomputer zur Unterstützung der kontinuierlichen Verfügbarkeit von Kapazität, um das Video in seiner größten Auflösung zu decodieren.

Die Realität ist jedoch, dass Netzwerk-Bandbreite für verbundene Heimcomputer kann mit der Zeit erheblich schwanken, und in bestimmten Teilen der Welt hoher Bandbreite bei einer sehr hohen Zulage stammt oder zahlreichen Consumern nicht zur Verfügung steht. Zusammen mit, kann die Verarbeitungskapazität des Clientcomputers, CPU-Auslastung zu einem bestimmten Zeitpunkt abhängig. Dies hat zur Folge, dass Consumer anfällig für die Beeinträchtigung der Qualität Ihrer Erfahrung anzeigen, wenn Sie ein Video stutters oder, fixiert während der Player genügend Daten zum Anzeigen der nächsten Satz von Videoframes, oder warten auf die CPU-Zyklen, die Rahmen zu decodieren gepuffert wartet.

Adaptives streaming ist ein video Übermittlung-Ansatz, der das Problem der reibungslose Inhaltsübermittlung und Decodieren von Adressen. Mit Adaptives streaming ist Videoinhalte auf einen Bereich von Bitraten codiert und über eine spezielle streaming-Server zur Verfügung gestellt. Ein adaptiver streaming Player ständig überwacht verschiedene Ressource Auslastung Metriken auf dem Clientcomputer und verwendet diese Informationen, um die entsprechenden Bitrate zu berechnen, die der Client am effizientesten decodieren und bei der angegebenen aktuellen Ressourcenbeschränkungen anzeigen kann.

Der Player fordert Abschnitte des Videos an, dass momentan entsprechende Bitrate codiert, und der streaming-Server antwortet mit Inhalten aus dem Videoquellen an, dass Bitrate codiert. Dies hat zur Folge, wenn Ressource Bedingungen beeinträchtigt werden, kann der Player weiterhin anzeigen des Videos ohne Störungen erheblichen mit nur eine leichte Herabsetzung der gesamten Lösung, bis eine Verbesserung oder weitere Herabsetzung der Bedingungen verursacht eine andere Bitrate angefordert werden soll.

Diese Art von einer fortlaufenden Zusammenarbeit zwischen dem Player und der Server erfordert eine spezielle Implementierung der Verarbeitungslogik auf streaming-Server und die Implementierung des Players Clientlaufzeit. Internet-Informationsdienste (IIS) Smooth Streaming ist die serverseitige Implementierung Adaptives streaming über HTTP von Microsoft. Die clientseitige Implementierung wird als Erweiterung für Microsoft Silverlight bereitgestellt.

Das IIS Smooth Streaming Player Development Kit ist eine Silverlight-Bibliothek, mit der Anwendungen Inhalt zu beanspruchen können über IIS Smooth Streaming gestreamt wird. Darüber hinaus gibt es eine Rich-API, die programmgesteuerten Zugriff auf verschiedene Aspekte der Smooth Streaming-Logik bietet.

In diesem Artikel ich die Grundlagen der Smooth Streaming durchgehen und erklären, wie Sie das IIS Smooth Streaming Player Development Kit verwendet werden können, um reichhaltige Benutzerfunktionalität um Video zu erstellen. Insbesondere betrachten ich mithilfe der Player Development Kit, um einen Stream mit einer schließen Untersuchung des clientseitigen Datenmodells für Streams und Spuren zu nutzen. Wird aufgezeigt, wie zusätzliche Datenströme wie Untertitel und Animationen, verbrauchen und externe Datenstreams mit einer vorhandenen Präsentation zusammenführen. Erfahren Sie, wie externe Clips zu planen, wie z. B. Ankündigungen innerhalb einer Präsentation behandeln Variable Wiedergabe Raten und zusammengesetzte Manifeste, die den stabilen Bearbeitung Szenarien erstellen.

Wie Smooth Streaming Works

Sie können für Smooth Streaming codieren Sie Videos mithilfe einer der angegebenen Profile in Expression Encoder 3.0. Für eine Quellvideodatei werden mehrere Dateien im Zielordner erstellt. Abbildung 1 zeigt die Dateien, die für eine Quelle video mit dem Namen FighterPilot.wmv erstellt.


Abbildung 1 für Weich generierte Dateien Streaming von Expression Encoder

Jede der Dateien mit der Erweiterung .ismv enthält das Video an eine bestimmte Bitrate codiert. Die FighterPilot_331.ismv enthält z. B. das Video mit einer Bitrate von 331 kbps codiert werden, während der FighterPilot_2056.ismv des Videos codiert, bei 2 Mbit/s enthält.

Für jede Bitrate der Videoinhalt ist in zwei-Sekunden-Fragmente aufgeteilt und die .ismv-Dateien speichern diese Fragmente in einem Dateiformat, das PIFF (Protected interoperabler File Format) bezeichnet. Beachten Sie, dass Sie können zusätzliche Audiospuren haben (oder nur audio im Fall der Präsentation audio nur) in ähnliche Dateien mit der Erweiterung .isma codiert.

Beim Abrufen der Streaming-Umgebung Weich

Die Beispiele in diesem Artikel beschriebenen testen möchten, müssen Sie die Vorbereitung einer Smooth Streaming-Umgebung auf Ihren Computern Entwicklung.

Die serverseitige Zutat ist einfach: Sie müssen zum Herunterladen und installieren IIS-Mediendienste 3.0 für IIS7 von iis.net/media mit dem Microsoft-Webplattform-Installer.

Sie müssen eine Kopie von Microsoft Expression Encoder 3.0 Smooth Streaming Video Vorbereitung. Es ist, zwar eine kostenlose Testversion von Expression Encoder 3.0 ist diese Version Unterstützung für Smooth Streaming nicht enthalten. Sie benötigen eine lizenzierte Installation von Expression Encoder, um Ihre eigenen Videos zu erstellen.

Weitere Informationen zur Vorbereitung Ihrer Umgebung finden Sie auf learn.iis.net/page.aspx/558/smooth-streaming-for-iis-70---getting-started von .

Die FighterPilot.ism-Datei ist ein Server-Manifest, das ist im SMIL (Synchronized Multimedia Integration Language)-Format strukturiert und enthält eine Zuordnung von Qualität und Bitraten zu den .ismv und .isma. Diese Zuordnung im Server-Manifest wird vom Server verwendet, für den Zugriff auf die richtigen Datenträgerdateien So erstellen Sie das nächste Fragment von Inhalten, die vor der Reaktion auf eine Clientanforderung der Seite mit der rechten Bitrate codiert. Abbildung 2 zeigt einen Auszug einer Manifestdatei Server.

Abbildung 2 Beispielserver Manifest

<smil xmlns="http://www.w3.org/2001/SMIL20/Language">
  <head>
    <meta name="clientManifestRelativePath"
      content="FighterPilot.ismc" />
  </head>
  <body>
    <switch>
      <video src="FighterPilot_2962.ismv"
        systemBitrate="2962000">
        <param name="trackID"
          value="2" valuetype="data" />
      </video>
      <video src="FighterPilot_2056.ismv"
        systemBitrate="2056000">
        <param name="trackID"
          value="2" valuetype="data" />
      </video>
      ...
      <audio src="FighterPilot_2962.ismv"
        systemBitrate="64000">
        <param name="trackID"
          value="1" valuetype="data" />
      </audio>
    </switch>
  </body>
</smil>

Das Server-Manifest enthält auch eine Zuordnung zu einer Client-manifest-Datei (identifiziert durch die Erweiterung .ismc), die in meinem Beispiel FighterPilot.ismc ist. Das Client-Manifest enthält alle Informationen, die, dass der Silverlight-Client Zugriff auf die verschiedenen Medien und Datenströme, sowie Metadaten zu dieser Streams, z. B. Qualitätsstufen, zur Verfügung, die vom Datentyp bit Raten Anzeigedauern für Informationen, Codec Initialisierungsdaten und so weiter muss. Die clientseitige Logik verwenden diese Metadaten (Beispiel) und Dekodieren der Fragmente und Bit Rate Switches anhand der zugeordnete lokale Bedingungen anfordern.

Zur Laufzeit beginnt die Präsentation mit dem Client das Manifest Client vom Server anfordern. Nachdem der Client das Manifest empfängt, prüft, welche Bitraten verfügbar sind und Fragmente von Inhalten beginnend mit der niedrigsten Verfügbare Bitrate anfordert. Als Reaktion der Server bereitet vor und sendet die Fragmente durch Lesen der Daten aus der Datenträgerdatei, die mit dieser Bitrate (verwenden die Zuordnung im Server-Manifest) codiert. Der Inhalt wird auf dem Client angezeigt.

Der Client fordert schrittweise höhere Bitraten als zulässig, indem Sie die Ressourcenüberwachung Logik und erreicht schließlich die höchste zulässige Bitrate wird durch die zugeordnete Ressource Bedingungen bestimmt. Dieser Austausch wird fortgesetzt, bis der Client Überwachung Logik eine Änderung der Ressource Bedingungen resultieren in einer anderen niedrigeren gewünschten Bitrate erkennt. Nachfolgende Clientanforderungen für Medien, die an die neue Bitrate codiert sind, und der Server antwortet erneut entsprechend. Dies geht auf, bis die Präsentation abgeschlossen oder beendet wird.

Glatte Streaming mit Silverlight

Video für die Wiedergabe in Silverlight ist ein relativ unkompliziert Aufwand. Eine grundlegende Ebene wirklich müssen Sie lediglich eine Instanz des Typs MediaElement zu XAML-Datei hinzufügen, legen Sie die entsprechenden Eigenschaften steuern das MediaElement-Verhalten, und stellen Sie sicher, dass die MediaElement.Source-Eigenschaft auf eine gültige Medienquelle URI verweist. Beispielsweise wird dieses XAML des FighterPilot.wmv Videos automatisch wiedergegeben, sobald die Silverlight-Seite in einem Rechteck 640 x 360 gestartet wird:

<MediaElement AutoPlay="True" 
  Source="http://localhost/Media/FighterPilot.wmv" 
  Width="640" Height="360" />

Der System.Windows.Controls.MediaElement-Typ verfügbar macht auch eine API, die Sie steuern das Verhalten der Wiedergabe Erfahrung in Code und zum Erstellen eines Players mit Standardsteuerelementen, z. B. Wiedergabe, Pause, Seek und so weiter ermöglicht. Dieser Ansatz funktioniert mit einem hervorragenden progressiv heruntergeladen oder HTTP-Medien per Streaming, solange das Container-Format und die verwendete Codierung ist einem mit integrierter Unterstützung für die Silverlight-Laufzeit.

Was Dateiformaten oder Codecs, die nicht aus dem Feld von Silverlight unterstützt werden? Die MediaStreamSource (MSS) ermöglicht eines Erweiterbarkeitsmechanismus, in dem Sie die Mediendatei analysieren und Decodieren von Prozess durch die Einführung von Ihren eigenen benutzerdefinierten Parser und -Decoder in Silverlight-Medienpipeline steuern kann. Zu diesem Zweck müssen Sie implementieren einen konkreten Typ abstrakte System.Windows.Media.MediaStreamSource zu erweitern, und übergeben Sie eine Instanz davon MediaElement, die mit der MediaElement.SetSource-Methode.

Die MSS-Implementierung müssen alle Aspekte des Prozesses Verbrauch Medien über das tatsächliche ausgeben ausreichend behandeln, empfängt den Medienstream von einem Remotestandort aus zu analysieren, den Container und die zugehörigen Metadaten sampling einzelne Audio und video Beispiele und übergibt Sie an MediaElement für das Rendering.

Da die notwendige Logik, um decodieren Smooth Streaming in Silverlight nicht integriert wurde, die erste Version der Smooth Streaming (Bestandteil von IIS-Mediendienste 2.0) wurde zusammen mit einer benutzerdefinierten MSS-Implementierung, die sämtliche Kommunikation, analysieren und Sampling Logik behandelt, und implementiert auch den Computer und Netzwerk-Statusüberwachung Funktionalität.

Zum größten Teil dieser Ansatz eignet sich für Smooth Streaming gearbeitet, aber es wurden einige Unzulänglichkeiten. Der MSS ist im Wesentlichen eine schwarze Kästchen, die einzige API direkt verfügbar gemacht zum Austausch von unformatierten Audio- und video Beispiele zwischen sich selbst und ein MediaElement zu erleichtern wird. Als Silverlight-Entwickler haben Sie keine direkte Möglichkeit, die Schnittstelle mit der maximalen SEGMENTGRÖßE in Aktion. Wenn der verbrauchten Inhalt zusätzliche Daten wie eingebettetem Text, Animation oder sekundäre Kamerawinkel hatte oder die streaming-Lösung für eine präzisere Kontrolle über die Datenströme zugelassen Variable Wiedergabe Raten gefällt, gab es keine Möglichkeit für die Sie für den programmgesteuerten Zugriff auf, dass zusätzliche Daten in einer strukturierten Weise weil Sie auf der Schnittstelle mit der feste API beschränkt waren, MediaElement immer festgelegt verfügbar macht.

Für Smooth Streaming stellt dies eine Herausforderung dar. Wie Sie weiter unten in diesem Artikel sehen werden, das Smooth Streaming Manifeste Wire-Datei-Formate sind ziemlich umfassenden hinsichtlich der zusätzliche Inhalt und Metadaten, die ausgeführt werden kann und mit der MSS-Ansatz Sie konnte nicht abgerufen werden, dass Informationen. Sie benötigen eine Silverlight-API, die mehr Kontrolle über und Zugriff auf das Smooth Streaming-Lösung bietet.

IIS glatt Streaming Player Development Kit

Und, bringt mich um das IIS Smooth Streaming Player Development Kit. Der Player Development Kit besteht aus einer einzelnen Assembly mit dem Namen 
Microsoft.Web.Media.SmoothStreaming.dll. Im Wesentlichen heißt ein Microsoft.Web.Media.SmoothStreaming.SmoothStreamingMediaElement (SSME). Mithilfe von SSME in Ihrem Code ist fast identisch mit der Weise, wie, die Sie eine reguläre MediaElement verwenden:

<UserControl x:Class="SSPlayer.Page"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
  xmlns:ss="clr-namespace:Microsoft.Web.Media.SmoothStreaming;assembly=Microsoft.Web.Media.SmoothStreaming">
  <Grid x:Name="LayoutRoot" Background="White">
    <ss:SmoothStreamingMediaElement AutoPlay="True" 
      Width="640" Height="360"
      SmoothStreamingSource="http://localhost/SmoothStreaming/Media/FighterPilot/FighterPilot.ism/manifest"/>
  </Grid>
</UserControl>

Die SmoothStreamingSource-Eigenschaft zeigt SSME auf eine gültige Smooth Streaming-Präsentation. Im Allgemeinen die SSME-API ist eine Obermenge der MediaElement-API; diese Eigenschaft ist einer der wenigen Unterschiede. SSME stellt die Source-Eigenschaft, wie MediaElement ist jedoch SSME auch die SmoothStreamingSource-Eigenschaft stellt, um glatte Streams zuordnen. Wenn Sie Spieler, die die Möglichkeit erstellen, die sowohl reibungslose Streams und andere Formate, die bisher von MediaElement unterstützt beanspruchen, können ohne weiteres SSME, aber wahrscheinlich müssen Sie Code zum Festlegen der richtigen-Eigenschaft Anfügen an die Medienquelle erstellen. Etwa so:

private void SetMediaSource(string MediaSourceUri, 
  SmoothStreamingMediaElement ssme) {

  if (MediaSourceUri.Contains(".ism"))
    ssme.SmoothStreamingSource = new Uri(MediaSourceUri); 
  else
    ssme.Source = new Uri(MediaSourceUri); 
}

Der wesentliche Unterschied zu beachten ist, dass SSME keine SetSource-Überladung verfügbar macht, die einen MediaStreamSource-Typ akzeptiert. Wenn Sie eine benutzerdefinierte MSS verwenden müssen, sollten Sie, bis MediaElement tun.

Streams und Titel

Das Smooth Streaming-Client-Manifest enthält umfangreiche Metadaten über die Präsentation, und es kann sinnvoll sein, über den programmgesteuerten Zugriff auf die Metadaten in Ihrer Player-Anwendung verfügen. SSME macht Teile dieser Metadaten über eine klar definierte API in eine Anordnung von Datenströmen und Titel innerhalb jeder Stream verfügbar.

Ein Stream die allgemeine Metadaten für den Titel eines bestimmten Typs darstellt, Video, Audio, Text, Ankündigungen und So weiter. Der Stream fungiert auch als Container für mehrere Titel desselben zugrunde liegenden Typs. In einer Client-Manifest (siehe Abbildung 3 ), jede StreamIndex-Eintrag repräsentiert einen Stream. Kann es mehrere Datenströme in der Präsentation, wie durch mehrere Einträge für die StreamIndex dargestellt. Es können auch mehrere Datenströme desselben Typs vorhanden sein. In solchen Fällen kann der Stream-Namen verwendet werden, um zwischen mehreren Vorkommen des gleichen Typs zu unterscheiden.

Abbildung 3 Auszug aus einer Client-Manifest

<SmoothStreamingMedia MajorVersion="2" MinorVersion="0" 
  Duration="1456860000">
  <StreamIndex Type="video" Chunks="73" QualityLevels="8" 
    MaxWidth="1280" MaxHeight="720" 
    DisplayWidth="1280" DisplayHeight="720"
    Url="QualityLevels({bitrate})/Fragments(video={start time})">
    <QualityLevel Index="0" Bitrate="2962000" FourCC="WVC1" 
      MaxWidth="1280" MaxHeight="720"
      CodecPrivateData="250000010FD37E27F1678A27F859E80490825A645A64400000010E5A67F840" />
    <QualityLevel Index="1" Bitrate="2056000" FourCC="WVC1" 
      MaxWidth="992" MaxHeight="560" 
      CodecPrivateData="250000010FD37E1EF1178A1EF845E8049081BEBE7D7CC00000010E5A67F840" />
    ...
    <c n="0" d="20020000" />
    <c n="1" d="20020000" />
    ...
    <c n="71" d="20020000" />
    <c n="72" d="15010001" />
  </StreamIndex>
  <StreamIndex Type="audio" Index="0" FourCC="WMAP" 
    Chunks="73" QualityLevels="1" 
    Url="QualityLevels({bitrate})/Fragments(audio={start time})">
    <QualityLevel Bitrate="64000" SamplingRate="44100" Channels="2" 
      BitsPerSample="16" PacketSize="2973" AudioTag="354" 
      CodecPrivateData="1000030000000000000000000000E00042C0" />
    <c n="0" d="21246187" />
    <c n="1" d="19620819" />
    ...
    <c n="71" d="19504762" />
    <c n="72" d="14900906" />
  </StreamIndex>
  <StreamIndex Type="text" Name="ClosedCaptions" Subtype="CAPT" 
    TimeScale="10000000" ParentStreamIndex="video" 
    ManifestOutput="TRUE" QualityLevels="1" Chunks="2" 
    Url="QualityLevels({bitrate},{CustomAttributes})/Fragments(ClosedCaptions={start time})">
    <QualityLevel Index="0" Bitrate="1000" 
      CodecPrivateData="" FourCC=""/> 
    <c n="0" t="100000000">
      <f>...</f> 
    </c>
    <c n="1" t="150000000">
      <f>...</f>
    </c>
  </StreamIndex>
  ...
</SmoothStreamingMedia>

Der StreamInfo-Typ darstellt, den Stream in Ihrem Silverlight-Code. Nach der SSME des Manifests Client heruntergeladen werden, löst das SmoothStreamingMediaElement.ManifestReady-Ereignis aus. Zu diesem Zeitpunkt enthält die SmoothStreamingMediaElement.AvailableStreams-Eigenschaft der Auflistung eine Instanz StreamInfo für jeden Eintrag StreamIndex im Client-Manifest.

Für einen bestimmten Videostream im Manifest Client der Videospur in viele Fragmente von zwei Sekunden Dauer unterteilt ist, und jedes C Element im Manifest darstellt, der Metadaten für das Fragment. In diesem Fall die Fragmente in der Spur sind zusammenhängend und definieren Sie die gesamte Dauer der Videospur ohne Unterbrechungen dazwischen – mit anderen Worten: der Datenstrom ist nicht mit geringer Datendichte.

Für einen Untertitel-Stream enthält der Titel nur zwei Fragmente, jeweils mit einzelnen Zeitgeberinformationen (im C-Element das Attribut "t"). Darüber hinaus wird das ParentStreamIndex-Attribut zu “ Videos ”, den Untertitel-Stream mit der Videostream Überordnung festgelegt. Dadurch wird den Untertitel-Stream, in der Zeitgeberinformationen aus den Videodatenstrom ausgerichtet, der Untertitel-Stream beginnt und endet genau mit seiner übergeordneten Videostream und die erste Beschriftung ist 10 Sekunden in der Videostream angezeigt, während der 
second 15 Sekunden in dem Video angezeigt wird. Ein Stream, in dem sich die Zeitachse basiert auf einem übergeordneten Stream und der Fragmente nicht angrenzend, ist einen gering gefüllten Stream aufgerufen.

Ein Titel ist einer zeitgesteuerten Folge von Fragmenten des Inhalts eines bestimmten Typs, Video, Audio oder Text. Jeder Titel wird mithilfe einer Instanz eines Typs TrackInfo dargestellt, und alle Spuren in einen Stream über das StreamInfo.AvailableTracks-Eigenschaft der Auflistung zur Verfügung gestellt werden.

Jeder Titel in einer Client-Manifest wird über eine QualityLevel eindeutig identifiziert. Eine QualityLevel wird identifiziert durch die zugeordneten Bitrate und wird über die TrackInfo.Bitrate-Eigenschaft zur Verfügung gestellt. Ein Videostream in einer Client-Manifest kann beispielsweise mehrere QualityLevels, jeweils mit einer eindeutigen Bitrate haben. Jeder repräsentiert eine eindeutige verfolgen des gleichen Videos Inhalt, an die durch die QualityLevel angegebene Bitrate codiert.

Benutzerdefinierte Attribute und Manifest-Ausgabe

Benutzerdefinierte Attribute sind eine Möglichkeit, zusätzliche Streams oder Track-spezifische Informationen zum Manifest hinzugefügt. Benutzerdefinierte Attribute werden mit einem CustomAttribute-Element, das mehrere Datenelemente, die als Schlüssel-Wert-Paare enthält, kann angegeben. Jedes Datenelement wird mit Schlüssel und Wert Attribute angeben, das Datenschlüssel-Element und den Datenwert für das Element als ein Element Attribute ausgedrückt. In Fällen, in denen verschiedene Qualitätsstufen nicht zutreffen, können z. B. mehrere Spuren in einen Stream mit der gleichnamigen Titel und Bitrate, ein benutzerdefiniertes Attribut auch verwendet werden um Spuren voneinander zu unterscheiden. Abbildung 4 zeigt ein Beispiel für die Verwendung des benutzerdefinierten Attributs.

Abbildung 4 mithilfe von benutzerdefinierten Attributen in das Client-Manifest

<StreamIndex Type="video" Chunks="12" QualityLevels="2" 
  MaxWidth="1280" MaxHeight="720" 
  DisplayWidth="1280" DisplayHeight="720" 
  Url="QualityLevels({bitrate})/Fragments(video={start time})">
  <CustomAttributes>
    <Attribute Key="CameraAngle" Value="RoofCam"/>
    <Attribute Key="AccessLevel" Value="PaidSubscription"/>
  </CustomAttributes>
  <QualityLevel Index="0" Bitrate="2962000" FourCC="WVC1" 
    MaxWidth="1280" MaxHeight="720"
    CodecPrivateData="250000010FD37E27F1678A27F859E80490825A645A64400000010E5A67F840">
    <CustomAttributes>
      <Attribute Name = "hardwareProfile" Value = "10000" />
    </CustomAttributes>
  </QualityLevel>
...
</StreamIndex>

Benutzerdefinierte Attribute hinzugefügt, um ein Manifest wirken ein SSME-Verhalten automatisch sich nicht auf. Sie sind eine Möglichkeit für die Produktion Workflow benutzerdefinierte Daten in das Manifest vor, mit denen der Player-Code empfangen und zu bearbeiten kann. Wenn z. B. in Abbildung 4 sollten Sie für den AccessLevel CustomAttribute-Schlüssel in der Auflistung Videostream benutzerdefinierte Attribute zu suchen und verfügbar machen, dass Videostreams nur für Abonnenten bezahlen, wie in der Wert des Attributs angewiesen.

Die StreamInfo.CustomAttributes-Eigenschaft der Auflistung stellt ein Wörterbuch von Schlüssel-Wert-Zeichenfolgenpaare für alle benutzerdefinierten Attribute, die auf der Ebene der Stream (als direkte CustomAttribute untergeordnete Elemente für das StreamIndex-Element) angewendet. Die TrackInfo.CustomAttributes-Eigenschaft stellt für alle benutzerdefinierten Attribute, die auf der Ebene der Spur (als direkte untergeordnete Elemente für das QualityLevel-Element) angewendet.

Wenn das ManifestOutput-Attribut (das StreamIndex-Element)-Stream auf TRUE festgelegt ist, kann das Client-Manifest tatsächlich die Daten, die jedes Fragment für den Titel im Stream darstellen enthalten. Abbildung 5 zeigt ein Beispiel dafür.

Abbildung 5 Manifest Ausgabe

<StreamIndex Type="text" Name="ClosedCaptions" Subtype="CAPT" 
  TimeScale="10000000" ParentStreamIndex="video" 
  ManifestOutput="TRUE" QualityLevels="1" Chunks="6" 
  Url="QualityLevels({bitrate},{CustomAttributes})/Fragments(ClosedCaptions={start time})"> 
  <QualityLevel Index="0" Bitrate="1000" CodecPrivateData="" FourCC=""/> 
  <c n="0" t="100000000">
    <f>PENhcHRpb24gSWQ9IntERTkwRkFDRC1CQzAxLTQzZjItQTRFQy02QTAxQTQ5QkFGQkJ9IiAKICAgICAgICBBY3Rp</f>
  </c>
  <c n="1" t="150000000">
    <f>PENhcHRpb24gSWQ9IntERTkwRkFDRC1CQzAxLTQzZjItQTRFQy02QTAxQTQ5QkFGQkJ9IiAKICAgI</f>
  </c>
...
</StreamIndex>

Beachten Sie die geschachtelte Inhalte innerhalb der f-Elemente – jeder repräsentiert die Beschriftung Artikeldaten, zu dem von der enthaltenden Abschnitt festgelegten Zeitpunkt angezeigt werden soll. Die Client-manifest-Spezifikation erfordert, dass die Daten als base64-codierte Zeichenfolgenversion des ursprünglichen Datenelements dargestellt werden.

Die TrackInfo.TrackData-Eigenschaft der Auflistung enthält eine Liste der TimelineEvent-Instanzen – eine für jedes entsprechende zum Titel f-Element. Für jeden Eintrag TimelineEvent TimelineEvent.EventTime den Zeitpunkt in der Reihenfolge darstellt, und die TimelineEvent.EventData die base64-codierte Zeichenfolge enthält. TrackInfo unterstützt auch die Bitrate, CustomAttributes, Index, Name und ParentStream Eigenschaften.

Datenströme und Titel auswählen

Es gibt viele interessante Möglichkeiten, die Sie im Anwendungscode des Streams und Spuren Metadaten und -API verwenden können.

Es kann sinnvoll sein, haben die Möglichkeit, wählen Sie bestimmte Spuren in einen Stream und der Rest herausfiltern. Ein übliches Szenario besteht eine abgestufte Ansicht Erfahrung basierend auf einem Abonnenten Zugriffsebene, in dem für einen Basisdatenträger oder einen kostenlosen Ebene dienen die niedrigauflösende Version des Inhalts, und die High-Definition-Version nur auf Anwendungsebene Premium-Abonnenten verfügbar zu machen:

if (subscriber.AccessLevel != "Premium") {
  StreamInfo videoStream = 
    ssme.GetStreamInfoForStreamType("video");
  List<TrackInfo> allowedTracks = 
    videoStream.AvailableTracks.Where((ti) => 
    ti.Bitrate < 1000000).ToList();
  ssme.SelectTracksForStream(
    videoStream, allowedTracks, false);
}

GetStreamInfoForStreamType akzeptiert ein literal Datenstromtyp und gibt die entsprechende StreamInfo-Instanz zurück. Eine LINQ-Abfrage auf StreamInfo.AvailableTracks Ruft eine Liste der Titel, die eine Bitrate von weniger als 1 Mbit/s bieten – mit anderen Worten: ein Standard-Definition-Videos für nicht-Premium-Abonnenten. SelectTracksForStream-Methode kann dann verwendet werden, um Sie in der Liste der Tracks im Stream um nur die Titel zu filtern, die Sie verfügbar machen möchten.

Der letzte Parameter, SelectTracksForStream, bei Einstellung auf true, gibt SSME, in die suchen-ahead-Puffer gespeicherten Daten sofort aus bereinigt werden sollten. Die aktuelle ausgewählte Liste der Tracks jederzeit zu erhalten, können Sie die StreamInfo.SelectedTracks-Eigenschaft verwenden, während die StreamInfo.AvailableTracks-Eigenschaft wird, fortgesetzt um alle verfügbaren Titel verfügbar zu machen.

Denken Sie daran, dass das Smooth Streaming mehrere Datenströme vom gleichen Typ, in das Manifest Client koexistieren können. In die aktuelle Betaversion von IIS Smooth Streaming Player Development Kit gibt die GetStreamInfoForStreamType-Methode das erste Vorkommen eines Streams vom angegebenen Typ zurück, für den Fall, dass es gibt mehrere Datenströme dieses Typs, der möglicherweise nicht wie Sie wünschen. Es ist jedoch keine Aktion beenden Sie diese Methode zu umgehen und stattdessen mithilfe einer Abfrage der AvailableStreams-Auflistung direkt an um das Recht StreamInfo zu erhalten. Der folgende Ausschnitt zeigt eine LINQ-Abfrage, die mit dem Namen “ Ticker ” Textstrom abruft:

StreamInfo tickerStream = 
  ssme.AvailableStreams.Where((stm) => 
  stm.Type == "text" && 
  stm.Name == "ticker").FirstOrDefault();

Verwenden die Text-Streams

Eine Audio-Video-Präsentation müssen möglicherweise zusätzliche Inhalte anzeigen, die zusammen die primäre Videosequenz an bestimmte Uhrzeit Punkten ist eine Zeitüberschreitung aufgetreten ist. Beispiele für konnte Untertitel, Ankündigungen, Neuigkeiten Warnungen, überlagern Animationen und so weiter. Ein Textstream ist eine bequeme Möglichkeit, solche Inhalte verfügbar zu machen.

Ein Ansatz zum Textstrom in der Präsentation enthalten würde zum Mux im Text-Spuren neben Videospuren während der Videocodierung sein, sodass Inhalte Segmente für den Titel, Text aus dem-Server entsprechend hat das Zeitlimit mit dem Video übermittelt werden.

Eine weitere Option besteht darin, zum Erstellen des Textinhalts in den Client-Manifest selbst weiter oben erläuterten manifest Ausgabe-Feature zu nutzen. Let’s näher an diesem zweiten Ansatz.

Um zu beginnen, müssen Sie ein Manifest Client bei der Textdatenströmen vorbereiten. In einem Workflow Produktion Medien können viele verschiedene Arten zu injizieren solche Inhalte in das Manifest während oder nach der Codierung und die Daten aus verschiedenen Quellen, wie z. B. Ad-Serving Plattformen und Beschriftung Generatoren kommen konnte vorhanden sein. Aber für dieses Beispiel werde ich eine einfache XML-Datei als Datenquelle verwenden, verwenden einige LINQ über XML-Abfragen, die Textdatenströme Herstellung und fügen Sie Sie in eine vorhandene Client-Manifest.

Die Struktur der Daten muss nicht komplex sein. (Sie können die vollständige Datei finden im Codedownload für diesen Artikel. Ich zeigt hier Auszüge für die Abbildung.) Die Datendatei beginnt mit einem Titel-Element und dann zwei ContentTrack-Elemente enthält. Jeder Eintrag ContentTrack führt letztendlich im Manifest Client eine unterschiedliche Textstream. Das erste Element der ContentTrack ist für die Beschriftungen:

<ContentTrack Name="ClosedCaptions" Subtype="CAPT">

Der zweite ist für Animationen:

<ContentTrack Name="Animations" Subtype="DATA">

Jeder ContentTrack enthält mehrere Ereignis-Elemente, mit der Zeitattribute, die die Laufzeit verweist auf das Video Zeitplan angeben, wenn diese Textereignisse auftreten müssen. Die Ereigniselemente enthalten wiederum die tatsächliche Beschriftung Ereignisse im XML- oder XAML für die Animation als CDATA-Abschnitte definiert:

<Event time="00:00:10"> 
  <![CDATA[<Caption Id="{DE90FACD-BC01-43f2-A4EC-6A01A49BAFBB}" 
    Action="ADD">
    Test Caption 1
  </Caption>] ]> 
</Event>
<Event time="00:00:15"> 
  <![CDATA[<Caption Id="{DE90FACD-BC01-43f2-A4EC-6A01A49BAFBB}" 
    Action="REMOVE"/>] ]> 
</Event>

Beachten Sie, dass für jedes Ereignis hinzugefügte Untertitel ein entsprechendes Ereignis, das den Zeitpunkt angibt, wenn die zuvor hinzugefügte Beschriftung muss entfernt werden. Das Caption-Element innerhalb des CDATA-Abschnitt für einen Untertitel-Ereignis definiert ein Action-Attribut mit einem Wert von hinzufügen oder entfernen, um anzugeben, dass die entsprechenden Aktion.

Meine LINQ über XML-Code transformiert die XML-Daten in die entsprechenden Einträge für einen Client-Manifest und eine vorhandene Client-Manifestdatei eingefügt. Sie finden ein Beispiel für die Verwendung im Codedownload für diesen Artikel, aber beachten Sie, dass das Datenformat gezeigt nicht Teil der Smooth Streaming Player Development Kit oder das Smooth Streaming-Spezifikation und keines von beiden ist ist es in keiner Weise normative. Sie können definieren, beliebige Datenstruktur Anforderungen Ihrer Anwendung, solange Sie transformieren können Sie in das entsprechende Format in der Smooth Streaming-Client-manifest Spezifikation umfasst den Textinhalt in den CDATA-Abschnitte in ein Format base64-Codierung erforderlich.

Nachdem die Transformation ausgeführt wird, wird die resultierende Client-Manifestdatei der Textdatenströme enthalten, wie in Abbildung 6 gezeigt.

Abbildung 6 Client Manifest mit Text Content Streams Auszug

<SmoothStreamingMedia MajorVersion="2" MinorVersion="0" 
  Duration="1456860000">
  <StreamIndex Type="video" Chunks="73" QualityLevels="8" 
    MaxWidth="1280" MaxHeight="720" 
    DisplayWidth="1280" DisplayHeight="720"
    Url="QualityLevels({bitrate})/Fragments(video={start time})">
    <QualityLevel Index="0" Bitrate="2962000" FourCC="WVC1" 
      MaxWidth="1280" MaxHeight="720"
      CodecPrivateData="250000010FD37E27F1678A27F859E80490825A645A64400000010E5A67F840" />
    <QualityLevel Index="1" Bitrate="2056000" FourCC="WVC1" 
      MaxWidth="992" MaxHeight="560" 
      CodecPrivateData="250000010FD37E1EF1178A1EF845E8049081BEBE7D7CC00000010E5A67F840" />
    ...
    <c n="0" d="20020000" />
    <c n="1" d="20020000" />
    ...
    <c n="71" d="20020000" />
    <c n="72" d="15010001" />
  </StreamIndex>
  <StreamIndex Type="audio" Index="0" FourCC="WMAP" 
    Chunks="73" QualityLevels="1" 
    Url="QualityLevels({bitrate})/Fragments(audio={start time})">
    <QualityLevel Bitrate="64000" SamplingRate="44100" Channels="2" 
      BitsPerSample="16" PacketSize="2973" AudioTag="354" 
      CodecPrivateData="1000030000000000000000000000E00042C0" />
    <c n="0" d="21246187" />
    <c n="1" d="19620819" />
    ...
    <c n="71" d="19504762" />
    <c n="72" d="14900906" />
  </StreamIndex>
  <StreamIndex Type="text" Name="ClosedCaptions" Subtype="CAPT" 
    TimeScale="10000000" ParentStreamIndex="video" 
    ManifestOutput="TRUE" QualityLevels="1" Chunks="2" 
    Url="QualityLevels({bitrate},{CustomAttributes})/Fragments(ClosedCaptions={start time})">
    <QualityLevel Index="0" Bitrate="1000" 
      CodecPrivateData="" FourCC=""/> 
    <c n="0" t="100000000">
      <f>...</f> 
    </c>
    <c n="1" t="150000000">
      <f>...</f>
    </c>
  </StreamIndex>
  ...
</SmoothStreamingMedia>

Das Video und audio Streams bereits vorhanden war im Client Manifest im Abbildung 6 angezeigt, und zwei Text-Streams, mit dem Namen ClosedCaptions und Animationen, jeweils hinzugefügt wurde. Beachten Sie, dass jeder Stream den Videostream als übergeordnetes Element verwendet und ManifestOutput auf True festgelegt. Die erste Möglichkeit ist, da die Textdatenströme sparse Natur sind und diese an den Videodatenstrom Überordnung stellt sicher, richtige Timing von jeder Inhalt Texteintrag (die C-Elemente) auf den Videodatenstrom Zeitachse dass. Die zweite besteht darin, sicherzustellen, dass die SSME die eigentlichen Daten (die base64-codierte Zeichenfolgen innerhalb der f-Elemente) liest aus dem Manifest selbst.

TimelineEvent und TimelineMarker

Nun betrachten let’s treffen Verwendung des Inhalts zusätzlicher Text in SSME. SSME macht zusätzliche Textdatenströme mit jeder StreamInfo, die mit den Daten verfolgen, wie eine Instanz TrackInfo als StreamInfo-Instanzen in der AvailableStreams-Eigenschaft verfügbar. Die TrackInfo.TrackData-Eigenschaft der Auflistung enthalten, wie viele Instanzen des Typs TimelineEvent dort Textereignisse in jeder Spur Text sind. Die TimelineEvent.EventData-Eigenschaft stellt ein Bytearray, das den Zeichenfolgeninhalt (decodiert aus seinem base64-codierten Format), während der TimelineEvent.EventTime-Eigenschaft den Zeitpunkt enthält, in denen dieses Ereignis auftreten muss, darstellt.

Beim Starten die Präsentation wiedergeben, da diese Ereignisse bereits erreicht werden löst SSME das TimelineEventReached-Ereignis. Abbildung 7 zeigt ein Beispiel der Umgang mit den Untertitel und Animation verfolgt, die die Client-Manifest in Abbildung 6 hinzugefügt wurden.

Abbildung 7 TimelineEventReached-Ereignis behandeln

ssme.TimelineEventReached += 
  new EventHandler<TimelineEventArgs>((s, e) => { 
  //if closed caption event
  if (e.Track.ParentStream.Name == "ClosedCaptions" && 
    e.Track.ParentStream.Subtype == "CAPT") {

    //base64 decode the content and load the XML fragment
    XElement xElem = XElement.Parse(
      Encoding.UTF8.GetString(e.Event.EventData,
      0, e.Event.EventData.Length));

    //if we are adding a caption
    if (xElem.Attribute("Action") != null && 
      xElem.Attribute("Action").Value == "ADD") {

      //remove the text block if it exists
      UIElement captionTextBlock = MediaElementContainer.Children.
      Where((uie) => uie is FrameworkElement && 
        (uie as FrameworkElement).Name == (xElem.Attribute("Id").Value)).
        FirstOrDefault() as UIElement;
        if(captionTextBlock != null)
          MediaElementContainer.Children.Remove(captionTextBlock);

      //add a TextBlock 
      MediaElementContainer.Children.Add(new TextBlock() {
        Name = xElem.Attribute("Id").Value,
        Text = xElem.Value,
        HorizontalAlignment = HorizontalAlignment.Center,
        VerticalAlignment = VerticalAlignment.Bottom,
        Margin = new Thickness(0, 0, 0, 20),
        Foreground = new SolidColorBrush(Colors.White),
        FontSize = 22
      });
    }
    //if we are removing a caption
    else if (xElem.Attribute("Action") != null && 
      xElem.Attribute("Action").Value == "REMOVE") {

      //remove the TextBlock
      MediaElementContainer.Children.Remove(
        MediaElementContainer.Children.Where(
        (uie) => uie is FrameworkElement && 
        (uie as FrameworkElement).Name == 
        (xElem.Attribute("Id").Value)).FirstOrDefault() 
        as UIElement);
    }
  }

  //Logic for animation event
  ...
});

Wie jede TimelineEvent behandelt wird, entweder einfügen ein TextBlock-Steuerelement der Benutzeroberfläche zur Anzeige einer Beschriftung oder laden die Animation XAML-Zeichenfolge und die Animation zu starten (den herunterladbaren Code für die Details der Animation-Verarbeitungslogik Siehe).

Beachten Sie, dass da des Textinhalts Base64-codiert ist, es in seinen ursprünglichen Zustand decodiert wird. Beachten Sie außerdem, dass der Code das Attribut Action für das Caption-Element überprüft zu entscheiden, ob es eine Beschriftung an der Benutzeroberfläche hinzufügen oder eine vorhandene Beschriftung entfernen. Für Animation Ereignisse können Sie eine der Animation abgeschlossen-Handler, von der Benutzeroberfläche zu entfernen abhängen.

Abbildung 8 zeigt einen Screenshot einer Beschriftung angezeigt wird, und eine Ellipse, die animiert wird auf eine Wiedergabe von Video überlagert. Obwohl dieser Ansatz gut funktioniert, liegt ein Problem, Sie berücksichtigen, bevor Sie dieses Verfahren verwenden müssen. Die aktuelle Version von SSME behandelt TimlineEvents, an den Begrenzungen der zwei Sekunden. Um dies besser verstehen zu können, mussten let’s sagen Sie ein Zeitlimit am 15.5 Sekunde Zeitpunkt entlang der Zeitachse video Untertitel. SSME TimelineEventReached-Ereignis für diese Untertitel am nächstgelegenen vorherigen Zeitpunkt, der ein Vielfaches von 2 auslösen würden – mit anderen Worten, bei ungefähr 14 Sekunden.


Abbildung 8 Content Overlay mit Text Content Datenströme und TimelineEvents

Wenn Ihr Szenario größere Genauigkeit fordert und Sie können nicht Ihre Inhalte Abschnitte nah an zwei Sekunden Grenzen positionieren, verwenden die TimelineEventReached zur Behandlung von Inhalten Spuren der richtige Weg möglicherweise nicht. Jedoch die TimelineMarker-Klasse (wie in der MediaElement Standardfeldtyp) können Sie den Zeitplan Marker hinzufügen, die das MarkerReached-Ereignis mit allen Granularität auslösen kann, die müssen Sie u. u.. Der Codedownload für diesen Artikel enthält die Gliederung einer AddAndHandleMarkers-Methode, die TimelineMarkers für jedes Ereignis Inhalte hinzugefügt, und reagiert auf diese im MarkerReached-Ereignishandler.

Zusammenführen von extern Manifests

Weiter oben wurde gezeigt, ein Beispiel für ein Manifest Client zusätzliche Streaminginhalt hinzugefügt. Dieser Ansatz funktioniert gut, wenn Sie Zugriff auf die Client-Manifest besitzen, aber es vorkommen können, direkter Zugriff auf die Client-Manifest, nehmen Sie Hinzufügungen zu die erforderlichen nicht möglich ist. Sie können auch Situationen, wo die zusätzliche Videoinhaltsdatenströme bedingt andere Faktoren (z. B. Untertitel in verschiedenen Sprachen für unterschiedliche Gebietsschemas) abhängen. Die Daten für alle möglichen Bedingungen hinzufügen, um das Client-Manifest bewirkt, dass SSME zu analysieren und laden das Manifest mehr Zeit aufwenden.

SSME löst dieses Problem, indem es Ihnen ermöglicht, externe manifest-Dateien zur Laufzeit in die ursprüngliche Client-Manifest Zusammenführen gibt Ihnen die Möglichkeit zu schalten, zusätzliche Datenströme und bearbeiten die Daten folgendermaßen vor, ohne das ursprüngliche Client-Manifest ändern zu müssen.

Hier ist ein Beispiel für die Verwendung des Manifests zusammenführen:

ssme.ManifestMerge += new 
  SmoothStreamingMediaElement.ManifestMergeHandler((sender) => {
  object ParsedExternalManifest = null;
  //URI of the right external manifest based on current locale
  //for example expands to 
  string UriString = 
    string.Format(
    "http://localhost/SmoothStreaming/Media/FighterPilot/{0}/CC.xml", 
    CultureInfo.CurrentCulture.Name);
  //parse the external manifest - timeout in 3 secs
  ssme.ParseExternalManifest(new Uri(UriString), 3000, 
    out ParsedExternalManifest);
  //merge the external manifest
  ssme.MergeExternalManifest(ParsedExternalManifest); 
});

Dieser Codeausschnitt Notizen zugeordnete Gebietsschema und verwendet eine entsprechende externe Manifestdatei (mit dem Namen CC.xml in einem Ordner mit dem Namen für die Sprachkennung für das Gebietsschema gespeichert), die Untertitel in der richtigen Sprache für dieses Gebietsschema enthält. Die ParseExternalManifest-Methode akzeptiert einen URI zeigen auf den Speicherort der externen Manifest und gibt das analysierte Manifest als ein Objekt über den dritten out-Parameter an die Methode zurück. Der zweite Parameter der Methode akzeptiert einen Timeoutwert, sodass Sie zu lang für den Netzwerk-Aufruf für die Blockierung vermeiden.

Die MergeExternalManifest-Methode akzeptiert das analysierte Manifestobjekt vom vorherigen Aufruf zurückgegeben und führt die eigentliche Zusammenführung. Im Anschluss an, die Streams Titel von jedem zusammengeführten externe Manifest zur Verfügung gestellt an anderer Stelle in Ihrer Player-Code als StreamInfo und TrackInfo-Instanzen und bei bearbeitet werden können, wie zuvor gezeigt.

Es ist wichtig zu beachten, dass die Aufrufe von ParseExternalManifest und MergeExternalManifest in ManifestMerge-Ereignishandler nur vorgenommen werden können. Alle Aufrufe dieser Methoden außerhalb des Gültigkeitsbereichs dieser Ereignishandler auszulösen eine InvalidOperationException aus.

Bedenken Sie, die externe Manifeste benötigen eine Erweiterung, die verfügt über einen zugeordneten MIME-Typ registriert wird, mit dem Webserver, die von dem aus Sie verfügbar sind. Mit der Erweiterung allgemeine wie z. B. XML eine gute Idee ist, da die Inhalte XML-ist trotzdem. Wenn die externen Manifesten-Dateien aus dem gleichen Webserver, die als Ihr Smooth Streaming-Server fungiert bereitgestellt werden, sollten Sie aus die .ismc-Erweiterung verwenden, da der IIS-Mediendienste-Handler verhindern, dass .ismc-Dateien direkt zugegriffen verzichten und ParseExternalManifest nach das externe Manifest downloaden fehl.

Soweit die Struktur ein externes Manifest verlässt, muss er mit einem Manifest regulären Clients identisch sein: ein SmoothStreamingMedia Element der obersten Ebene, mit der entsprechenden StreamIndex untergeordnete Elemente aus, um Ihre Daten darstellen.

Clip-Kapazitätsplanung

Sie können die Notwendigkeit, zusätzliche Videoclips in eine Präsentation zu bestimmten Zeitpunkt Zeitpunkten einfügen konfrontiert. Ankündigung Videos, wichtige News oder Fülltage Clips in eine Präsentation sind nur einige Beispiele. Das Problem kann in zwei Teilen angezeigt werden. Erste Erwerb der erforderlichen Inhaltsdaten und bestimmen, wo in der Zeitachse, um ihn einzufügen. Zweite tatsächlich Zeitplanung und die Clips abspielen. SSME enthält Funktionen, die diese beiden Aufgaben relativ einfach zu implementieren.

Sie können weiterhin den Ansatz, ein Textstream eingefügt, in das Manifest-Client verwenden, wie in den vorherigen Abschnitten dargestellt, um die Clip-Daten in den Code zur Verfügung zu stellen. Hier ist eine Beispieldatenquelle, die für die Zeitplaninformationen Clip verwendet:

<ContentTrack Name="AdClips" Subtype="DATA">
  <Event time="00:00:04">
    <![CDATA[<Clip Id="{89F92331-8501-41ac-B78A-F83F6DD4CB40}" 
    Uri="http://localhost/SmoothStreaming/Media/Robotica/Robotica_1080.ism/manifest" 
    ClickThruUri="https://msdn.microsoft.com/en-us/robotics/default.aspx" 
    Duration="00:00:20" />] ]>
  </Event>
  <Event time="00:00:10">
    <![CDATA[<Clip Id="{3E5169F0-A08A-4c31-BBAD-5ED51C2BAD21}" 
    Uri="http://localhost/ProgDownload/Amazon_1080.wmv" 
    ClickThruUri="http://en.wikipedia.org/wiki/Amazon_Rainforest" 
    Duration="00:00:25"/>] ]>
  </Event>     
</ContentTrack>

Für jeden Clip zu planende ein URI für den Inhalt vorhanden ist, einen URI für eine Webseite der Benutzer kann navigieren Sie zu als ein Click-bis auf den Clip, und eine Wiedergabedauer für den Clip. Das Zeit Attribut im Element-Ereignis gibt an, die in der Zeitachse der Clip geplant werden.

Diese Daten zu transformieren, und fügen Sie den entsprechenden Textstream in das Manifest Client den gleichen Ansatz von einer LINQ zu XML-Abfrage verwenden, wie im vorherigen Abschnitt beschrieben. Als wird vor, der Textstream an den Code als eine StreamInfo-Instanz verfügbar gemacht. Den Clip-API auf der SSME Planung können Sie um diese Informationen so planen Sie diese Clips zu nutzen. Abbildung 9 zeigt eine Methode, die die Clips anhand dieser Informationen berechnet.

Abbildung 9- Schduling Clips

private void ScheduleClips() {
  //get the clip data stream
  StreamInfo siAdClips = ssme.AvailableStreams.Where(
    si => si.Name == "AdClips").FirstOrDefault();

  //if we have tracks
  if (siAdClips != null && siAdClips.AvailableTracks.Count > 0) {

    //for each event in that track
    foreach (TimelineEvent te in 
      siAdClips.AvailableTracks[0].TrackData) {

      //parse the inner XML fragment
      XElement xeClipData = XElement.Parse(
        Encoding.UTF8.GetString(te.EventData, 0, 
        te.EventData.Length));

      //schedule the clip
      ssme.ScheduleClip(new ClipInformation {
        ClickThroughUrl = new Uri(
        xeClipData.Attribute("ClickThruUri").Value),
        ClipUrl = new Uri(xeClipData.Attribute("Uri").Value),
        IsSmoothStreamingSource = 
        xeClipData.Attribute("Uri").Value.ToUpper().Contains("ism"), 
        Duration = TimeSpan.Parse(xeClipData.Attribute("Duration").Value)
        },
        te.EventTime, true, //pause the timeline
        null);
    }
    //set the Clip MediaElement style
    ssme.ClipMediaElementStyle = 
      this.Resources["ClipStyle"] as Style;
  }
}

Die ScheduleClip-Methode für SSME ist die tatsächliche Terminplanung. Für jeden Clip, den Sie planen möchten, wird eine neue Instanz der ClipInformation-Typ in den Terminplan mit den entsprechenden Eigenschaften aus der Clip Daten abgeleitet eingefügt.

Beachten Sie, dass Clips Smooth Streaming-Datenquellen oder anderen Quellen können wie von der Silverlight-MediaElement unterstützt. Es ist wichtig, die ClipInformation.IsSmoothStreamingSource-Eigenschaft richtig zu setzen, um sicherzustellen, dass die richtigen Player-Komponente verwendet wird, um die Clipwiedergabe zu starten.

Der zweite Parameter ScheduleClip ist die Zeit, wenn Sie den Clip wiedergeben möchten. Der dritte Parameter wird verwendet, um anzugeben, ob Sie die Zeitachse fortschreitet während der Wiedergabe des Clips stoppen möchten. Der letzte Parameter wird verwendet, um alle Benutzerdaten übergeben, die mit der verschiedenen Clip-bezogene Ereignishandler zur Verfügung gestellt wird.

In einigen Fällen müssen Clips Startzeit Informationen nur auf den ersten Clip in einer Sequenz angewendet wird, und nachfolgende Clips sind verkettet, so dass alle geplanten Clips in eine fortlaufende Abfolge wiedergegeben werden in einer Sequenz geplant werden. Die ScheduleClip-Methode erleichtert dieses Feature auch, wie in Abbildung 10 .

Abbildung 10 Clips mit ClipContext zu Chain geplante

private void ScheduleClips() {
  StreamInfo siAdClips = ssme.AvailableStreams.Where(
  si => si.Name == "AdClips").FirstOrDefault();

  if (siAdClips != null && siAdClips.AvailableTracks.Count > 0) {
    ClipContext clipCtx = null;
    foreach (
      TimelineEvent te in siAdClips.AvailableTracks[0].TrackData) {
      XElement xeClipData = 
        XElement.Parse(Encoding.UTF8.GetString(te.EventData, 0,
        te.EventData.Length));

      //if this is the first clip to be scheduled
      if (clipCtx == null) {
        clipCtx = ssme.ScheduleClip(new ClipInformation {
          ClickThroughUrl = new Uri(
          xeClipData.Attribute("ClickThruUri").Value),
          ClipUrl = new Uri(xeClipData.Attribute("Uri").Value),
          IsSmoothStreamingSource = 
          xeClipData.Attribute("Uri").Value.ToUpper().Contains("ism"), 
          Duration = TimeSpan.Parse(
          xeClipData.Attribute("Duration").Value)
        },
        te.EventTime, //pass in the start time for the clip
        true, null);
      }
      else { //subsequent clips
        clipCtx = ssme.ScheduleClip(new ClipInformation {
          ClickThroughUrl = new Uri(
          xeClipData.Attribute("ClickThruUri").Value),
          ClipUrl = new Uri(xeClipData.Attribute("Uri").Value),
          IsSmoothStreamingSource = 
          xeClipData.Attribute("Uri").Value.ToUpper().Contains("ism"),
          Duration = TimeSpan.Parse(
          xeClipData.Attribute("Duration").Value)
        },
        clipCtx, //clip context for the previous clip to chain
        true, null);
      }
    }
    ssme.ClipMediaElementStyle = 
      this.Resources["ClipStyle"] as Style;
  }
}

Ich verwende eine absolute Zeit nur um den ersten Clip zu planen, wenn keine ClipContext (anders ausgedrückt: die Variable ClipCtx ist null). Jedem nachfolgender Aufruf von ScheduleClip gibt eine ClipContext-Instanz, die den geplanten Zustand des Clips darstellt. Die ScheduleClip-Methode hat eine Überladung, die akzeptiert einer ClipContext-Instanz, anstatt eine geplante Startzeit für einen Clip, und, plant den Clip, um nach den vorher geplanten Zeitpunkt Clip (dargestellt durch den übergebenen ClipContext) zu starten.

Wenn die geplante Clips abspielen, SSME Blendet das Hauptfenster Video und führt ein MediaElement, um die geplante Clipwiedergabe zu starten. Für den Fall, dass Sie diese MediaElement anpassen möchten, können Sie auf SSME die ClipMediaElementStyle-Eigenschaft um eine gewünschte XAML-Format festlegen.

Es gibt auch mehrere Ereignisse von Interesse, die von SSME ausgelöst werden, während ein geplanter Clip wiedergegeben wird. Das ClipProgressUpdate-Ereignis kann behandelt werden, um den Fortschritt des Clips zu verfolgen. ClipPlaybackEventArgs.Progress ist des Enumerationstyps ClipProgress, die den Clip Fortschritt in QUARTILE darstellt. Das ClipProgressUpdate-Ereignis wird ausgelöst, nur am Anfang und Ende den Clip und zur Laufzeit verweist, die 25 %, 50 % und 75 Prozent der Dauer des Clips angibt. Beachten Sie, dass die boolesche Eigenschaft ClipContext.HasQuartileEvents angibt, ob die Quartile-Ereignisse für einen Clip ausgelöst werden. In bestimmten Fällen, z. B. wenn die Dauer für einen Clip nicht bekannt ist möglicherweise Quartil Fortschrittereignisse nicht ausgelöst werden.

Das ClipClickThrough-Ereignis wird ausgelöst, wenn der Viewer auf einen Clip, klickt während Sie es anzeigen. Klicken Sie auf über Ziel für diesen Clip vorgesehen war, ClipEventArgs.ClipContext.ClipInformation.ClickThroughUrl macht Sie verfügbar und können Sie eine Methode Ihrer Wahl (z. B. das interagieren mit dem Browser um ein Popup-Fenster zu öffnen), bis die Webressource Ziel über URL - klicken Sie dann auf Öffnen.

Auch können das ClipError-Ereignis und das ClipStateChanged-Ereignis Sie um alle Fehlerbedingungen und Statusänderungen für den Clip zu behandeln. 

Wiedergabe der Geschwindigkeit und der Richtung

SSME ermöglicht die Wiedergabe von Inhalt mit unterschiedlichen Geschwindigkeiten und Richtung. Die SmoothStreamingMediaElement.SupportedPlaybackRates-Eigenschaft gibt eine Liste der unterstützten Wiedergabe Geschwindigkeiten als double-Werten, 1.0, in dem die Standard-Wiedergabegeschwindigkeit kennzeichnet. In der aktuellen öffentliche Betaversion enthält diese Liste die zusätzlichen Werte von 0,5, 4.0, 8.0,-4.0 und-8.0. Positive Werte Wiedergabe zur Hälfte aktivieren, 4 X 8 X-Geschwindigkeit und negative Werte reverse wiedergeben (Rücklauf) 4 X und 8 X-Geschwindigkeiten.

Die SmoothStreamingMediaElement.SetPlaybackRate-Methode kann aufgerufen werden, um die Geschwindigkeit der Wiedergabe zu irgendeinem Zeitpunkt während der Wiedergabe festgelegt. SetPlaybackRate werden die gewünschten Wiedergabegeschwindigkeit als einzigen Parameter akzeptiert.

Beachten Sie, dass steuern die Wiedergabegeschwindigkeit nur für Smooth Streaming-Inhalte funktioniert, sodass wenn Inhalte wiederzugeben, für die progressiv heruntergeladen oder gestreamt mit einigen anderen Verfahren von SSME mithilfe, SetPlaybackRate eine Ausnahme auslöst.

Glatte Stream Bearbeitungen Composite Manifeste verwenden

Manchmal müssen Sie möglicherweise Teile aus mehreren Smooth Streaming-Präsentationen in einer einzigen zusammengesetzten Präsentation kombinieren. Das häufigste Szenario ist Tools wie Editoren Rough-cut verwenden, die es Benutzern ermöglichen, die Markierung in und Mark-Out-Punkt in einem master Quellcode erzeugt Clips und müssen dann linear als eine einzelne Präsentation mehrere solche Clips von potenziell verschiedene master Quellen Wiedergabe angeben.

Das Feature für kombinierte manifest des SSME können Sie erreichen, indem Sie das Erstellen eines separaten Manifesten Dokuments, das Clip-Segmente enthält, wobei jedes Segment Clip einen Teil eine vollständige Präsentation, die durch die Anfangs- und Enddatum Zeit Punkt des Clips begrenzt definiert. Der größte Vorteil der Verwendung dieser Ansatz ist die Fähigkeit zum Erstellen von verschiedener Bearbeitungen auf vorhandenen Präsentationen, ohne dass das Quellmaterial transcodieren.

Ein zusammengesetztes Manifest endet immer mit der Erweiterung .csm. Solche Manifest nutzen legen Sie einfach die SmoothStreamingSource-Eigenschaft in einen gültigen URL auf eine zusammengesetzte manifest-Datei verweist:

ssme.SmoothStreamingSource = new Uri("http://localhost/SmoothStreaming/Media/MyCompositeSample.csm");

Abbildung 11 zeigt einen Auszug aus einer zusammengesetzten Manifest. (Die gesamte Datei ist in der Code herunterladen für diesen Artikel enthalten.)

Abbildung 11 Composite-Beispiel-Manifest

<?xml version="1.0" encoding="utf-8"?>
<SmoothStreamingMedia MajorVersion="2" MinorVersion="0" Duration="269000000">
<Clip Url="http://localhost/SmoothStreaming/Media/AmazingCaves/Amazing_Caves_1080.ism/manifest" 
  ClipBegin="81000000" ClipEnd="250000000">
<StreamIndex Type="video" Chunks="9" QualityLevels="3"
  MaxWidth="992" MaxHeight="560"
  DisplayWidth="992" DisplayHeight="560"
  Url="QualityLevels({bitrate})/Fragments(video={start time})">
  <QualityLevel Index="0" Bitrate="2056000" FourCC="WVC1"
    MaxWidth="992" MaxHeight="560"
    CodecPrivateData="250000010FD37E1EF1178A1EF845E8049081BEBE7D7CC00000010E5A67F840" 
  />
  <QualityLevel Index="1" Bitrate="1427000" FourCC="WVC1"
    MaxWidth="768" MaxHeight="432"
    CodecPrivateData="250000010FCB6C17F0D78A17F835E8049081AB8BD718400000010E5A67F840" 
  />
  <QualityLevel Index="2" Bitrate="991000" FourCC="WVC1"
    MaxWidth="592" MaxHeight="332"
    CodecPrivateData="250000010FCB5E1270A58A127829680490811E3DF8F8400000010E5A67F840" 
  />
  <c t="80130000" />
  <c t="100150000" />
  <c t="120170000" />
  <c t="140190000" />
  <c t="160210000" />
  <c t="180230000" />
  <c t="200250000" />
  <c t="220270000" />
  <c t="240290000" d="20020000" />
</StreamIndex>
<StreamIndex Type="audio" Index="0" FourCC="WMAP"
  Chunks="10" QualityLevels="1" 
  Url="QualityLevels({bitrate})/Fragments(audio={start time})">
  <QualityLevel Bitrate="64000" SamplingRate="44100"
    Channels="2" BitsPerSample="16" PacketSize="2973"
    AudioTag="354" CodecPrivateData="1000030000000000000000000000E00042C0" />
  <c t="63506576" />
  <c t="81734240" />
  <c t="102632199" />
  <c t="121672562" />
  <c t="142106122" />
  <c t="162075283" />
  <c t="181580045" />
  <c t="202478004" />
  <c t="222447165" />
  <c t="241313378" d="20143311" />
</StreamIndex>
</Clip>
<Clip Url="http://localhost/SmoothStreaming/Media/CoralReef/Coral_Reef_Adventure_1080.ism/manifest" 
  ClipBegin="102000000" ClipEnd="202000000">
<StreamIndex Type="video" Chunks="6" QualityLevels="3"
  MaxWidth="992" MaxHeight="560"
  DisplayWidth="992" DisplayHeight="560"
  Url="QualityLevels({bitrate})/Fragments(video={start time})">
...
</Clip>
</SmoothStreamingMedia>

Dieses Manifest enthält zwei Clip-Elemente, die jede Definition eines Clips (auch als Bearbeitung genannt) aus einer vorhandenen Smooth Streaming-Präsentation. Der URL-Attribut verweist auf eine vorhandene Smooth Streaming-Präsentation und die ClipBegin und ClipEnd-Attribute enthalten, die Anfangs- und Endwerte Zeit, die die Begrenzungen auf den Clip zu bieten. Das Duration-Attribut auf das Element der obersten Ebene SmoothStreamingMedia muss der genaue Summe der Dauer für jeden Clip in das Manifest werden – Sie können die Differenz der ClipEnd und ClipBegin Werte jedes Eintrags Clip zum Abrufen der Gesamtdauer des Manifesten summieren.

Jedes Element Clip enthält das Video und audio StreamIndex und deren untergeordneten QualityLevel-Einträge des Clients spiegeln Manifestdateien (.ismc) von der Quelle Präsentationen. Die Block-Metadateneinträge (c) für jeden Eintrag StreamIndex können jedoch auf nur die Segmente beschränkt werden, die erforderlich sind, um die Begrenzungen für ClipBegin und ClipEnd zu erfüllen. Anders ausgedrückt, muss der ClipBegin-Wert größer als oder gleich den Startwert für die Zeit (t-Attribut) des ersten Eintrags C für den Stream und der Wert muss kleiner oder gleich der Summe von der Startzeit entfernt sein ClipEnd und die Werte für die Dauer (d-Attribut) des letzten c für diesen Stream.

Beachten Sie, dass in Ihrem Manifest Client Segmenten in einer Weise indizierte (n Attribut) mit der angegebenen Dauer definiert werden können. Allerdings müssen für das zusammengesetzte Manifest die Segmente mit Ihren Startzeiten (was leicht berechnet werden können durch Aufsummieren der Dauer von der vorherigen Abschnitte) definiert werden. Beachten Sie außerdem Attributs Segmente für jeden Eintrag StreamIndex muss entsprechend die Anzahl von Segmenten in dem Clip, dass alle anderen Attribute spiegeln die Einträge im Manifest Client Quelle.

Live-Streams

Bedarfsgesteuerte und live-Streams kann SSME wiedergegeben werden. Einen live-Smooth Streaming Videostream mit SSME wiedergegeben werden soll, können Sie die SmoothStreamingSource-Eigenschaft auf SSME zu einem live publishing Point-URL festlegen:

ssme.SmoothStreamingSource = "http://localhost/SmoothStreaming/Media/FighterPilotLive.isml/manifest";

Wissen Sie, wenn SSME einen Livestream wiedergegeben wird, können Sie die IsLive-Eigenschaft überprüfen, die auf True festgelegt ist, wenn der Inhalt einer Livequelle False, andernfalls ist.

Beachten Sie, dass die Einrichtung und Bereitstellung von Smooth Streaming video live erfordert spezielle Infrastruktur. Eine ausführliche Beschreibung der Einrichtung einer live-streaming Serverumgebung ist Gegenstand dieses Artikels. Sie finden in den Artikeln unter learn.iis.net/page.aspx/628/live-smooth-streaming/ für Weitere Informationen zum Einrichten von IIS-Mediendienste 3.0 für live-streaming. Im Artikel learn.iis.net/page.aspx/620/live-smooth-streaming-for-iis-70---getting-started/ von werden Ihnen Informationen über das Einrichten einer Simulation einer live-streaming-Umgebung zu Testzwecken bereitgestellt.

Zusammenfassung

IIS Smooth Streaming ist eine adaptive streaming Plattform, die neuesten von Microsoft. Wie haben Sie gesehen, das Smooth Streaming-PDK (und in bestimmten SmoothStreamingMediaElement-Typ) ist ein wichtiger Bestandteil zum Entwickeln von Silverlight-Clients, die bedarfsgesteuerte und live-Streams in Anspruch nehmen. Die PDK bietet umfassende Steuerungsmöglichkeiten für das Verhalten des clientseitigen reibungslose Streams und ermöglicht es Ihnen, umfassende schreiben und beeindruckende Erfahrungen, die nur Audio/Video-Streams hinausgehen, sodass Sie problemlos Datenströme mit Ihrer Medien auf sinnvolle Weise kombinieren.

Eine ausführliche Behandlung Smooth Streaming würde den Rahmen dieses Artikels sprengen. Sie werden aufgefordert, Weitere Einzelheiten finden Sie unter Iis. NET/Medien. Weitere Anleitungen zur Programmierung in Silverlight und den Silverlight-MediaElement Medien finden Sie auf silverlight.net/getstarted.

 

Jit Ghosh Ein Architekt Evangelist im Developer Evangelism-Team bei Microsoft, Raten von Debitoren in der Branche Medien zum Erstellen von digitalen Medien topaktuelle Lösungen ist. Ghosh Mitverfasser des Buches “ Silverlight Rezepte ” (APress, 2009). Sie können seinen Blog unter blogs.msdn.com/jitghosh lesen.

Dank an den folgenden technischen Experten für die Überprüfung dieses Artikels: Vishal Sood