Compartir a través de


Este artículo proviene de un motor de traducción automática.

IIS Smooth Streaming

Mejoramiento de las experiencias de vídeo de Silverlight con datos contextuales

Jit Ghosh

Descargar el ejemplo de código

Existen dos requisitos principales para habilitar una experiencia de visualización sin problemas en la entrega de vídeo digital basada en Web, la alta definición. En primer lugar, el proveedor de vídeo debe admitir velocidades de bits de entrega de vídeo de alta a través de la red. En segundo lugar, el equipo cliente necesita admitir la disponibilidad continua de capacidad para descodificar el vídeo en su resolución al máximo de procesamiento.

Sin embargo, la realidad es que puede fluctuar considerablemente ancho de banda de red para equipos domésticos conectados a lo largo del tiempo y en determinadas partes del mundo gran ancho de banda trata de una prima muy alta o no está disponible para muchos consumidores. Junto con la, la capacidad de procesamiento del equipo cliente puede variar, dependiendo de la carga de CPU en un momento dado. Como resultado, los consumidores son susceptibles a la degradación de la calidad de su experiencia de visualización cuando un vídeo se reproduce de forma intermitente o se bloquea mientras espera el Reproductor para suficientes datos para mostrar el siguiente conjunto de fotogramas de vídeo o esperando a que los ciclos de CPU en descodificar aquellas tramas del búfer.

Transmisión por secuencias adaptativa es un enfoque de entrega de vídeo que soluciona el problema de entrega de contenido suave y descodificación. Con la transmisión por secuencias adaptativa, contenido de vídeo es codificado a una gama de velocidades de bits y disponible a través de un servidor de streaming especializado. Un Reproductor de transmisión por secuencias adaptativo constantemente supervisa diversas métricas de utilización de recursos en el equipo cliente y utiliza esa información para calcular la velocidad de bits adecuado que el cliente de la forma más eficaz puede descodificar y mostrar en dadas las restricciones de recursos actual.

El Reproductor solicita fragmentos del vídeo codificado a esa velocidad de bits adecuado en ese momento y el servidor de transmisión responde con contenido de los orígenes de vídeo codificados a esa velocidad de bits. Como resultado, cuando las condiciones de recursos, puede resultar el Reproductor puede continuar mostrando el vídeo sin cualquier interrupciones importantes, con sólo una ligera degradación general resolución, hasta que una mejora o degradación aún más en condiciones hace que una velocidad de bits diferente que se va a solicitar.

Este tipo de una colaboración continua entre el Reproductor y el servidor requiere una implementación especial de procesar la lógica en el servidor de transmisión por secuencias y el motor de ejecución del cliente implementar el Reproductor. Smooth Streaming de Internet Information Server (IIS) es la implementación de servidor de transmisión por secuencias adaptativa a través de HTTP de Microsoft. La implementación de cliente se proporciona como una extensión para Microsoft Silverlight.

El IIS suavizado Streaming Reproductor Development Kit es una biblioteca de Silverlight permite a las aplicaciones de consumir contenido que se está transmitiendo a través de IIS Smooth Streaming. También proporciona una API enriquecida que ofrece acceso mediante programación a distintos aspectos de la lógica Smooth Streaming.

En este artículo se le guiarán a través de los conceptos básicos de Smooth Streaming y explique cómo puede utilizar el IIS suavizado Streaming Reproductor Kit de desarrollo para crear experiencias enriquecidas alrededor de vídeo. Específicamente, examinará con el Kit de desarrollo Reproductor para consumir una secuencia, con un examen detenido del modelo de datos de cliente para secuencias y las pistas. Le mostraré cómo consumir secuencias de datos adicionales, como los títulos cerrados y animaciones y combinar secuencias de datos externos con una presentación existente. Verá cómo programar clips externos, como anuncios dentro de una presentación, controlar las tasas de reproducción variable y generar manifiestos compuestos que prestó sólidos escenarios de edición.

Cómo suavizar Works transmisión por secuencias

Para codificar vídeo para Smooth Streaming mediante uno de los perfiles proporcionados en Expression Encoder 3.0. Un archivo de vídeo de origen, se crean varios archivos en la carpeta de destino. La figura 1 muestra los archivos creados para un vídeo de origen llamado FighterPilot.wmv.


Figura 1 de transmisión por secuencias archivos generados suave (Smooth) en Expression Encoder

Cada uno de los archivos con una extensión .ismv contiene el vídeo codificado a una velocidad de bits específico. Por ejemplo, el FighterPilot_331.ismv contiene vídeo codificado a una velocidad de bits de 331 kbps, mientras que FighterPilot_2056.ismv contiene vídeo codificado a 2 mbps.

Para cada velocidad de bits, el contenido de vídeo se divide en fragmentos de dos segundos y archivos .ismv almacenen estos fragmentos en un formato de archivo denominado formato de archivo interoperables protegido (PIFF). Nota que puede hacer que las pistas de audio adicionales (o sólo audio en caso de la presentación es audio sólo) se codifica en archivos similares que tienen la extensión .isma.

Obteniendo suavizar entorno de transmisión por secuencias

Para probar los ejemplos descritos en este artículo, debe preparar un entorno Smooth Streaming en los equipos de desarrollo.

El ingrediente de servidor es sencillo: deberá descargar e instalar IIS Media Services 3.0 para IIS7 desde de iis.net/media utilizando al instalador de Microsoft Web Platform.

Necesitará una copia de Microsoft Expression Encoder 3.0 para preparar vídeo Smooth Streaming. Aunque hay una versión de evaluación gratuita de Expression Encoder 3.0, dicha versión no incluye soporte para Smooth Streaming. Necesitará una instalación con licencia de Expression Encoder para crear su propio vídeo.

Para obtener detalles adicionales sobre la preparación de su entorno, visite learn.iis.net/page.aspx/558/smooth-streaming-for-iis-70---getting-started .

El archivo FighterPilot.ism es un manifiesto de servidor, que se estructura en formato de lenguaje de integración multimedia sincronizada (SMIL) y contiene una asignación de niveles de calidad y las velocidades de bits a los archivos .ismv y .isma. Esta asignación en el manifiesto de servidor se utiliza el servidor para tener acceso a los archivos de disco adecuado para crear el siguiente fragmento de contenido codificado a la velocidad de bits adecuado, antes de responder a una solicitud del lado cliente. Figura 2 muestra un extracto de un archivo de manifiesto de servidor.

Figura 2 Sample Server 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>

El manifiesto de servidor también contiene una asignación a un archivo de manifiesto de cliente (identificado por la extensión .ismc), que en mi ejemplo es FighterPilot.ismc. El manifiesto del cliente contiene toda la información que el cliente de Silverlight necesita tener acceso a la diversos medios y secuencias de datos, así como las tasas de metadatos sobre esas secuencias, como los niveles de calidad, disponibles de bits, información, datos de inicialización de códec de intervalos y así sucesivamente. La lógica del lado cliente utilizará estos metadatos para muestrear y descodificar los fragmentos y solicitar cambia de velocidad de bits basándose en las condiciones locales preponderantes.

En tiempo de ejecución, la presentación comienza con el cliente solicita el manifiesto del cliente al servidor. Una vez que el cliente recibe el manifiesto, se comprueba qué velocidades de bits están disponibles y solicita fragmentos de contenido empezando por la velocidad de bits disponible inferior. En respuesta, el servidor prepara y envía los fragmentos leyendo los datos del archivo de disco codificado a esa velocidad de bits (mediante la asignación en el manifiesto del servidor). El contenido se muestra a continuación, en el cliente.

El cliente solicita gradualmente velocidades de bits más altas como permitido por la lógica de supervisión de recursos y finalmente alcance la velocidad de bits permitido más alta determinado por las condiciones imperantes de recurso. Este intercambio continúa hasta que la lógica de supervisión del cliente detecta un cambio en condiciones de recursos, lo que da como resultado una velocidad de bits deseada menor diferentes. Las posteriores solicitudes del cliente son para los medios codificados con la nueva velocidad de bits y el servidor vuelve a responde en consecuencia. Esto va hasta que la presentación completa o se detiene.

Transmisión por secuencias suave con Silverlight

Obtener vídeo para reproducir en Silverlight es un esfuerzo bastante poco complicado. En un nivel fundamental, todo lo que se necesita hacer es agregar una instancia del tipo MediaElement a su archivo XAML, establezca las propiedades adecuadas para controlar el comportamiento de MediaElement y asegúrese de que la propiedad MediaElement.Source apunta a un identificador URI de origen de medio válido. Por ejemplo, este XAML reproducirá el vídeo FighterPilot.wmv automáticamente en cuanto se inicia la página de Silverlight, en un rectángulo de 640 x 360:

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

El tipo de System.Windows.Controls.MediaElement también expone una API que le permite controlar el comportamiento de la experiencia de reproducción en el código y para generar un reproductor completo con controles estándar, como reproducir, pausar, Seek y así sucesivamente. Este funciona enfoque perfectamente con cualquiera progresivamente descargada o HTTP transmitidos por secuencias multimedia siempre que sea que el motor en tiempo de ejecución de Silverlight tiene compatibilidad integrada para el formato de contenedor y la codificación utilizada.

¿Qué sucede con formatos de archivo o códecs que no son compatibles de forma inmediata con Silverlight? El tipo de MediaStreamSource (MSS) permite a un mecanismo de extensibilidad que le permite tomar control del archivo multimedia del análisis y del proceso de descodificación introduciendo su propio analizador personalizado y el descodificador en la canalización multimedia de Silverlight. Para hacer esto, necesita implementar un tipo concreto extender System.Windows.Media.MediaStreamSource abstracta y, a continuación, pase una instancia de ella a MediaElement mediante el método MediaElement.SetSource.

Será necesario controlar cada aspecto del proceso de consumo medios de la representación real de la implementación de MSS: reciba la transmisión desde una ubicación remota para analizar el contenedor y los metadatos asociados para toma de muestras audio individual y vídeo ejemplos y pasar a MediaElement para la representación.

Dado que la lógica necesaria para descodificar Smooth Streaming no fue incorporada de Silverlight, la versión primera de Smooth Streaming (que forma parte de IIS Media Services 2.0) era acompañada de una implementación personalizada de MSS que controla todas las comunicaciones, analizar y lógica de muestreo y también implementa el equipo y funcionalidad de supervisión de estado de la red.

La mayoría de los casos, este enfoque funcionaba bien para Smooth Streaming, pero se produjeron algunas deficiencias. El tamaño máximo de segmento es esencialmente una caja negra en que es la única API expone directamente facilitar el intercambio de audio sin procesar y muestras de vídeo entre sí y un elemento MediaElement. Como desarrollador de Silverlight, no tiene una forma directa de interfaz con el tamaño máximo de segmento mientras se encuentra en la acción. Si el contenido que se va a consumir tenía datos adicionales como texto incrustado, animación o ángulos de cámara secundaria o si la solución de transmisión por secuencias permitida para un control más preciso sobre las secuencias como las tasas de reproducción variable, no había forma para que obtener acceso mediante programación a que datos adicionales en una manera estructurada como estaban limitadas a interactuar con la API fija establecen ese MediaElement siempre expone.

Para Smooth Streaming, esto supone un desafío. Como verá más adelante en este artículo, Smooth Streaming manifiestos y formatos de archivo/cable son bastante enriquecidos en términos de contenido adicional y metadatos que se pueden llevar a y con el enfoque de MSS no se puede obtener en esa información. Necesita una API de Silverlight que ofrece más control sobre y el acceso a la solución Smooth Streaming.

Kit de desarrollo del Reproductor de transmisión por secuencias suave de IIS

Y eso me lleva a la IIS suavizado Streaming Kit de desarrollo del Reproductor. El Kit de desarrollo del Reproductor está formado por un único ensamblado denominado 
Microsoft.Web.Media.SmoothStreaming.dll. En esencia es un tipo de llamada Microsoft.Web.Media.SmoothStreaming.SmoothStreamingMediaElement (SSME). Utiliza SSME en el código es casi idéntica a la manera que utilizaría un MediaElement regular:

<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>

La propiedad SmoothStreamingSource apunta SSME a una presentación Smooth Streaming válida. En general, la API SSME es un superconjunto de la API de MediaElement; esta propiedad es una de las pocas diferencias. SSME expone la propiedad Source igual que hace de MediaElement pero SSME también expone la propiedad SmoothStreamingSource para adjuntar a secuencias suaves. Si va a crear los reproductores que necesitan la capacidad de consumir secuencias suaves y los otros formatos compatibles tradicionalmente con MediaElement, puede utilizar de forma segura SSME, pero probablemente tendrá que crear algún código para establecer la propiedad derecha para adjuntar el origen multimedia. De esta forma:

private void SetMediaSource(string MediaSourceUri, 
  SmoothStreamingMediaElement ssme) {

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

La principal diferencia que deben tenerse en cuenta es que SSME no exponer una sobrecarga SetSource que acepta un tipo MediaStreamSource. Si necesita utilizar un tamaño máximo de segmento personalizado, debe hacer a través de MediaElement.

Secuencias de actividades y secuencias

El manifiesto del cliente Smooth Streaming contiene metadatos enriquecidos acerca de la presentación y puede ser útil tener acceso mediante programación a esos metadatos dentro de la aplicación de Reproductor. SSME expone partes de estos metadatos a través de una API bien definido en una disposición de las secuencias y las pistas dentro de cada secuencia.

Una secuencia representa los metadatos general para las pistas de un tipo específico: vídeo, audio, texto, anuncios y así sucesivamente. La secuencia también actúa como contenedor para varias pistas del mismo tipo subyacente. En un manifiesto de cliente (consulte de figura 3), cada entrada StreamIndex representa una secuencia. Puede haber varias secuencias en la presentación, como se describe en las distintas entradas StreamIndex. También puede haber varias secuencias del mismo tipo. En tales casos, el nombre de la secuencia puede utilizarse para eliminar la ambigüedad entre varias apariciones del mismo tipo.

Figura 3 del extracto de un manifiesto de cliente

<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>

El tipo de StreamInfo representa la secuencia en el código de Silverlight. Una vez SSME descarga el manifiesto del cliente, provoca el evento SmoothStreamingMediaElement.ManifestReady. En este momento la propiedad de colección SmoothStreamingMediaElement.AvailableStreams contiene una instancia StreamInfo para cada entrada StreamIndex en el manifiesto del cliente.

Para una secuencia de vídeo determinada en el manifiesto del cliente, la pista de vídeo se divide en muchos fragmentos de duración de dos segundos y cada elemento c en el manifiesto representa metadatos para el fragmento. En este caso, los fragmentos de la pista son contiguos y definir toda la duración de la pista de vídeo sin los saltos de página entre ellas — es decir, la secuencia no es dispersa.

Para obtener un flujo de subtítulos, la pista incluye sólo dos fragmentos, cada uno con información de temporización individuales (el atributo en el elemento c t). Además, el atributo ParentStreamIndex se establece en “ vídeo ”, se establece una relación de primario-secundario entre la secuencia de subtítulos con la secuencia de vídeo. Esto hace que la secuencia de subtítulos para alinearse con la información de temporización de la secuencia de vídeo: la secuencia de subtítulos empieza y termina exactamente en su secuencia de vídeo principal y el primer título se muestra 10 segundos en la secuencia de vídeo mientras la 
second se muestra 15 segundos en el vídeo. Una secuencia en la que la escala de tiempo se basa en una secuencia principal y los fragmentos son no contiguos se llama a una secuencia dispersa.

Una pista es una secuencia programada de fragmentos de contenido de un tipo específico: vídeo, audio o texto. Cada pista se representa mediante una instancia de un tipo TrackInfo y todas las pistas en una secuencia estarán disponibles a través de la propiedad de colección StreamInfo.AvailableTracks.

Cada pista en un manifiesto de cliente se identifica mediante un QualityLevel. Un QualityLevel identificado por la velocidad de bits asociado y se expone a través de la propiedad TrackInfo.bitrate. Por ejemplo, una secuencia de vídeo en un manifiesto de cliente puede tener varios QualityLevels, cada uno con una velocidad de bits únicos. Cada una representa una única pista del vídeo mismo contenido, codificados a la velocidad de bits especificada por el QualityLevel.

Atributos personalizados y manifiesto de salida

Los atributos personalizados son una forma para agregar información de secuencia o pista específica al manifiesto. Los atributos personalizados se especifican mediante un elemento CustomAttribute, que puede contener varios elementos de datos, expresados como pares clave/valor. Cada elemento de datos se expresa como un elemento de atributo con atributos de clave y valor especificando la clave de elemento de datos y el valor de elemento de datos. En casos donde no se aplican los niveles de calidad diferenciados, como varias pistas dentro de una secuencia con el mismo nombre de pista y velocidad de bits, un atributo personalizado pueden también utilizarse para eliminar la ambigüedad de las pistas entre sí. Figura 4 muestra un ejemplo de uso de atributos personalizados.

Figura 4 de utilizar atributos personalizados en el manifiesto del cliente

<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>

Los atributos personalizados agregados a un manifiesto no afectan a cualquier comportamiento SSME automáticamente. Son un modo para que introducir datos personalizados en el manifiesto que el código del Reproductor puede recibir y actuar sobre el flujo de trabajo de producción. Por ejemplo, en de figura 4, desea buscar la clave de atributo personalizado AccessLevel en la colección de atributos personalizados de secuencia de vídeo y exponer esa secuencia de vídeo sólo a pagar los suscriptores, tal como se indica en el valor del atributo.

La propiedad de colección StreamInfo.CustomAttributes expone un diccionario de pares de clave y valor de cadena de todos los atributos personalizados aplicados en el nivel de secuencia (como directos CustomAttribute a los elementos secundarios del elemento StreamIndex). La propiedad TrackInfo.CustomAttributes expone el mismo para todos los atributos personalizados aplicados en el nivel de pista (como elementos secundarios directos al elemento QualityLevel).

Cuando el atributo ManifestOutput en la secuencia (elemento StreamIndex) está establecido en TRUE, el manifiesto de cliente realmente puede contener los datos que representan cada fragmento para las pistas dentro de la secuencia. En la figura 5 se muestra un ejemplo.

Figura 5 de manifiesto de salida

<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>

Tenga en cuenta el contenido anidado dentro de los elementos de f, cada uno representa datos de elemento de título que se van a mostrar a la hora especificada por el fragmento que lo contiene. La especificación de manifiesto del cliente requiere que los datos se representan como una versión de cadena codificada en base64 del elemento de datos original.

La propiedad de colección TrackInfo.TrackData contiene una lista de instancias de TimelineEvent: uno para cada elemento de f correspondiente a la pista. Para cada entrada de TimelineEvent TimelineEvent.EventTime representa el punto de tiempo en la secuencia y el TimelineEvent.EventData proporciona la cadena de texto codificado en base64. TrackInfo también admite propiedades de la velocidad de bits, CustomAttributes, índice, nombre y ParentStream.

Seleccionar secuencias y secuencias de actividades

Hay muchas maneras interesantes que puede utilizar las secuencias y metadatos de pistas y API en el código de la aplicación.

Puede ser útil tener la capacidad para seleccionar pistas específicas dentro de una secuencia y filtrar el resto. Un escenario común es una experiencia de visualización calificada basada en nivel de un suscriptor de acceso, donde para un nivel básico o libre servir la versión de baja resolución del contenido y exponer la versión de alta definición sólo para suscriptores de nivel premium:

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 acepta un literal de tipo de secuencia y devuelve la instancia StreamInfo coincidente. Una consulta LINQ en StreamInfo.AvailableTracks recupera una lista de pistas que ofrecen una velocidad de bits de menos de 1 mbps: en otras palabras, un vídeo de definición estándar para los suscriptores no premium. El método SelectTracksForStream, a continuación, se puede utilizar para filtrar la lista de pistas en esa secuencia a sólo las pistas que desea exponer.

El último parámetro a SelectTracksForStream, cuando se establece en true, indica a SSME que ninguno de los datos almacenados en los búferes de búsqueda anticipada debe limpiarse inmediatamente. Para obtener la lista seleccionada actual de pistas en cualquier momento, puede utilizar la propiedad StreamInfo.SelectedTracks mientras continúa la propiedad StreamInfo.AvailableTracks exponer las pistas disponibles.

Recuerde que Smooth Streaming permite varias secuencias del mismo tipo que pueden coexistir en el manifiesto del cliente. En la actual versión beta del IIS Smooth Streaming Reproductor Kit de desarrollo de, el método GetStreamInfoForStreamType devuelve la primera aparición de una secuencia del tipo especificado en caso de que haya varias secuencias de ese tipo, lo cual puede no ser que desee. Sin embargo, no hay nada que impida que omitan este método y utilizar en su lugar una consulta en la colección AvailableStreams directamente para obtener el derecho StreamInfo. El fragmento de código siguiente muestra una consulta LINQ que obtiene una secuencia de texto denominada “ ticker ”:

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

Utilizar secuencias de texto

Una presentación de audio y vídeo posible que deba mostrar contenido adicional que se ha superado el tiempo a lo largo de la secuencia de vídeo principal en puntos de tiempo específico. Ejemplos podría ser títulos cerrados, anuncios, noticias alertas, superponer animaciones y así sucesivamente. Una secuencia de texto es un lugar cómodo para exponer este tipo de contenido.

Un método para incluir una secuencia de texto en la presentación sería mux en las pistas de texto junto con las pistas de vídeo durante la codificación de vídeo, para que se entreguen los fragmentos de contenido de la pista de texto desde el servidor ha superado el tiempo adecuadamente con el vídeo.

Otra opción es utilizar la característica de manifiesto de salida se explicó anteriormente para crear el contenido de texto en el manifiesto del cliente. Let’s eche un vistazo al este segundo enfoque.

Para empezar, debe preparar un manifiesto de cliente con las secuencias de texto. En un flujo de trabajo de medios de producción, puede haber muchas formas de insertar dicho contenido en el manifiesto durante o después de codificación y los datos no se podrían proceder de diversos orígenes, como plataformas anuncio Servers y generadores de título. Sin embargo, en este ejemplo, voy a utilizar un archivo de datos XML sencillo como el origen de datos, utilizar algunos LINQ a través de consultas XML para fabricar las secuencias de texto y insertarlos en un manifiesto de cliente existente.

La estructura de los datos no tiene que ser compleja. (Encontrará el archivo completo en la descarga de código para este artículo. Voy a mostrar extractos aquí con fines ilustrativos.) El archivo de datos comienza con un elemento de pistas y, a continuación, contiene dos elementos ContentTrack. Cada entrada ContentTrack en última instancia, se producirá una secuencia de texto distintos en el manifiesto del cliente. El primer elemento ContentTrack es para los títulos:

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

La segunda es para animaciones:

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

Cada ContentTrack contiene varios elementos de evento, con los atributos de tiempo especifican los puntos de tiempo en escala de tiempo del vídeo cuando necesita se producen estos eventos de texto. Los elementos de evento a su vez contienen los eventos de título real definidos en XML o el código XAML para la animación como las secciones CDATA:

<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>

Tenga en cuenta que para cada evento subtítulos agregado es un evento correspondiente que indica el punto de tiempo cuando el título previamente agregado debe quitarse. El elemento CAPTION contenido en la sección CDATA para un evento de subtítulos define un atributo de acción con un valor de agregar o eliminar para indicar la acción apropiada.

Mi LINQ sobre el código XML transforma los datos XML en entradas correspondientes a un manifiesto de cliente y los inserta en un archivo de manifiesto de cliente existente. Puede encontrar un ejemplo en la descarga de código para este artículo, pero tenga en cuenta que el formato de datos de muestra no es una parte del Kit de desarrollo de Reproductor de transmisión por secuencias suave o la especificación Smooth Streaming y ninguno es preceptiva en modo alguno. Puede definir cualquier estructura de datos se adapte a las necesidades de su aplicación, siempre y cuando puede transformar en el formato apropiado requerido por la Smooth Streaming cliente manifiesto especificación, que incluye la codificación del contenido de texto en las secciones CDATA en un formato en base64.

Una vez que se ejecuta la transformación, el archivo de manifiesto resultante del cliente contendrá las secuencias de texto como se muestra en de figura 6.

Figura 6 de cliente manifiesto excerpt con secuencias de contenido de texto

<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>

El vídeo y secuencias de audio ya existían en el manifiesto del cliente que se muestra en de figura 6 y agregué las secuencias de texto de dos, denominadas ClosedCaptions y animaciones, respectivamente. Tenga en cuenta que cada secuencia utiliza la secuencia de vídeo como su elemento primario y establece ManifestOutput en true. El primero es porque las secuencias de texto son dispersas por naturaleza y se establece una relación de primario-secundario entre ellos en la secuencia de vídeo garantiza temporización correcta de cada movimiento de contenido de texto (los elementos c) a lo largo de escala de tiempo de la secuencia del vídeo. El último es asegurar que la SSME lee los datos reales (las cadenas con codificación base64 dentro de los elementos de la f) desde el propio manifiesto.

TimelineEvent y TimelineMarker

Ahora let’s mirar hacer uso del contenido de texto adicional en SSME. SSME expone las secuencias de texto adicional como StreamInfo instancias en la propiedad AvailableStreams, con cada StreamInfo que contiene los datos de seguimiento como una instancia TrackInfo. La propiedad de colección TrackInfo.TrackData contendrá como muchas instancias del tipo TimelineEvent porque no hay son eventos de texto en cada pista de texto. La propiedad TimelineEvent.EventData expone una matriz de bytes que representa el contenido cadena (descodificado desde su formato codificado en base64) al TimelineEvent.EventTime propiedad expone el punto de tiempo que debe producirse este evento.

Al iniciar reproducir la presentación se alcanzan estos eventos, SSME provoca el evento TimelineEventReached. Figura 7 muestra un ejemplo de manejo del subtítulo y pistas de animación que se agregaron al manifiesto del cliente en de figura 6.

Figura 7 controlar el evento TimelineEventReached

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
  ...
});

Como controlado cada TimelineEvent, o bien insertar un TextBlock en la interfaz de usuario para mostrar un título o cargar la cadena XAML animación e iniciar la animación (vea el código descargable para obtener más información acerca de la lógica de control de animación).

Tenga en cuenta que dado que el contenido de texto es base 64 codificado, se descodifica a su estado original. Tenga en cuenta también que el código comprueba el atributo de acción en el elemento CAPTION para decidir si se agrega un título a la interfaz de usuario o quitar un título existente. Para los eventos de animación, puede confiar en un controlador de finalización de la animación para quitarlo de la interfaz de usuario.

Figura 8 muestra una captura de pantalla de un título que se muestra y una elipse que se va a animar situados en una reproducción de vídeo. Aunque este enfoque funciona bien, hay un problema que debe tener en cuenta antes de utilizar esta técnica. La versión actual de SSME controla TimlineEvents en los límites de dos segundos. Para comprender mejor, diga let’s tuviera un subtítulos ha superado el tiempo en el punto de tiempo de 15,5 segundo a lo largo de la escala de tiempo de vídeo. SSME podría provocar el evento TimelineEventReached para este título cerrado en el punto de tiempo anterior más cercano que es un múltiplo de 2: en otras palabras, en aproximadamente 14 segundos.


Figura 8 de secuencias de contenido de texto de uso de contenido superpuesto y TimelineEvents

Si su escenario exige mayor precisión y no se puede situar sus fragmentos contenidos cercanos a los límites de dos segundos, mediante el TimelineEventReached para controlar las pistas de contenido no sea la forma correcta. Sin embargo, puede utilizar la clase TimelineMarker (tal como se usa en el tipo de MediaElement estándar) para agregar marcadores a la escala de tiempo que puede provocar el evento MarkerReached en cualquier granularidad que necesite. La descarga de código de este artículo incluye el contorno de un método AddAndHandleMarkers que agrega TimelineMarkers para cada evento contenido y responde en el controlador de eventos MarkerReached.

Manifiestos de combinación externa

Anteriormente ha visto un ejemplo de cómo agregar secuencias adicionales de contenido en un manifiesto de cliente. Ese enfoque funciona bien si tiene acceso al manifiesto de cliente, pero puede haber situaciones donde no es posible el acceso directo al manifiesto de cliente para realizar las adiciones necesarias. También puede haber situaciones donde las secuencias de contenido adicionales dependen condicionalmente otros factores (por ejemplo, subtítulos en diferentes idiomas para distintas configuraciones regionales). Agrega los datos para todas las condiciones posibles al manifiesto de cliente, SSME dedicar más tiempo a analizar y cargar el manifiesto.

SSME resuelve este problema al permitirle combinar archivos de manifiesto externos en tiempo de ejecución en el manifiesto del cliente original, que proporciona a la capacidad de poner en secuencias de datos adicionales y actuar sobre los datos tal como se muestra antes, sin tener que modificar el manifiesto del cliente original.

Aquí es un ejemplo de combinación de manifiesto:

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); 
});

Este fragmento de código notas de la configuración regional dominantes y utiliza un adecuado manifiesto archivo externo (denominado CC.xml almacenados en una carpeta con nombre para el identificador de idioma para la configuración regional) que contiene los títulos cerrados en el idioma apropiado para esa configuración regional. El método ParseExternalManifest acepta un URI que apunta a la ubicación del manifiesto externo y devuelve el manifiesto analizado como un objeto mediante el tercer parámetro de salida al método. El segundo parámetro para el método acepta un valor de tiempo de espera, lo que permite evitar el bloqueo es demasiado larga en la llamada de red.

El método MergeExternalManifest acepta el objeto de manifiesto analizado devuelve la llamada anterior y realiza la combinación real. A continuación, el secuencias pistas desde cualquier manifiesto externo combinada se ponen a disposición en cualquier lugar en el código de Reproductor como StreamInfo y TrackInfo instancias y se pueden actuar como se muestra anteriormente.

Es importante destacar que las llamadas a ParseExternalManifest y MergeExternalManifest sólo pueden realizarse en el controlador de eventos ManifestMerge. Todas las llamadas a estos métodos fuera del alcance de este controlador de eventos provocan una excepción InvalidOperationException.

Tenga en cuenta que los manifiestos externos deben tener una extensión que tiene un tipo MIME asociado registrado con el servidor Web desde el que estén disponibles. El uso de una extensión comunes, como .xml es una buena idea, porque el contenido es XML es todos modos. Si los archivos de manifiesto externos se sirven desde el mismo servidor Web que actúa como su servidor Smooth Streaming, deben abstenerse de utilizar la extensión .ismc porque el controlador de servicios de IIS Media impide .ismc archivos que se tiene acceso directamente y ParseExternalManifest no podrá descargar el manifiesto externo.

Lo que queda fuera de la estructura de un manifiesto externo, debe ser idéntico al manifiesto de clientes habituales: un SmoothStreamingMedia elemento de nivel superior, con elementos de secundarios StreamIndex adecuados para representar los datos.

Programación de clip

Pueden enfrentar la necesidad de insertar clips de vídeo adicionales en una presentación en los puntos de tiempo específico. Vídeos de anuncio, dividir los clips de noticias o relleno de una presentación son tan sólo unos ejemplos. El problema se puede ver en dos partes. En primer lugar, adquirir los datos de contenido necesarios y determinar dónde en la línea de tiempo para insertarlo. Segundo, realmente la programación y reproducir los clips. SSME incorpora funcionalidad realiza ambas tareas bastante sencilla de implementar.

Puede continuar utilice el enfoque de una secuencia de texto inserta en el manifiesto del cliente, como se ilustra en las secciones anteriores, para que los datos del clip esté disponible para su código. Éste es un origen de datos de ejemplo para obtener información de programación de clip:

<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>

Para cada clip programarse hay un identificador URI para el contenido, un identificador URI para una página Web el usuario puede desplazarse como una click-through en el clip y una duración de reproducción del clip. El atributo de hora en el elemento de evento especifica dónde está programado el clip en la línea de tiempo.

Puede transformar estos datos y agregar la secuencia de texto correspondiente en el manifiesto del cliente, utilizando el mismo enfoque de un LINQ a XML consulta tal y como se describe en la sección anterior. Como antes, la secuencia de texto se expone al código como una instancia StreamInfo. A continuación, puede utilizar el clip de programación API en el SSME para utilizar esta información para programar estos clips. Figura 9 muestra un método que programa los clips según esta información.

Figura 9 de 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;
  }
}

El método ScheduleClip en SSME no programación real. Para cada clip que desee programar, se inserta una nueva instancia de tipo ClipInformation en la programación con las propiedades adecuadas derivarse de los datos de clip.

Tenga en cuenta que el clips puede Smooth Streaming orígenes u otros orígenes tal y como lo admita el MediaElement de Silverlight. Es importante establecer la propiedad ClipInformation.IsSmoothStreamingSource correctamente para asegurarse de que el componente Reproductor derecho se utiliza para reproducir el clip.

El segundo parámetro ScheduleClip es la hora a la que desea reproducir el clip. El tercer parámetro se utiliza para indicar si se desea la escala de tiempo detener progresan mientras se esté reproduciendo el clip. El último parámetro se utiliza para pasar datos de usuario que estará disponibles con varios controladores de evento relacionado con el clip.

A veces clips necesitan programarse en una secuencia donde la información de hora de inicio se aplica sólo al primer clip en una secuencia y los clips subsiguientes se encadenan en el modo que todos los clips programados jugar en una secuencia continua. El método ScheduleClip facilita esta característica también, como se muestra en de figura 10.

Figura 10 Using ClipContext a cadena programadas clips

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;
  }
}

Use sólo una hora absoluta para programar el primer clip cuando no hay ningún ClipContext (es decir, la variable clipCtx es null). Cada llamada posterior al ScheduleClip devuelve una instancia de ClipContext que representa el estado programado del clip. El método ScheduleClip tiene una sobrecarga que acepta una instancia ClipContext en lugar de una hora de inicio programada para un clip y programaciones que el clip comience justo después del clip programado con anterioridad (representado por ClipContext pasado).

Al reproducir los clips programados, SSME oculta el vídeo principal y presenta un MediaElement para reproducir el clip programado. En caso de que desea personalizar esta MediaElement, puede establecer la propiedad ClipMediaElementStyle en SSME en un estilo XAML que desee.

También hay varios eventos de interés que se producen al SSME mientras se reproduce un clip programado. El evento ClipProgressUpdate puede controlarse para realizar un seguimiento del progreso del clip. ClipPlaybackEventArgs.Progress es del tipo de enumeración ClipProgress, que representa el progreso del clip en quartiles. Se provoca el evento ClipProgressUpdate sólo al principio y al final del clip y en los puntos de tiempo que denota el 25 por ciento, 50 % y 75 % de la duración del clip. Tenga en cuenta que la propiedad booleana ClipContext.HasQuartileEvents indica si los eventos cuartil se generará un clip. En ciertos casos, al igual que cuando no se conoce la duración de un clip, no podrán elevarse cuartil eventos de progreso.

Se provoca el evento ClipClickThrough cuando el Visor hace clic en un clip mientras lo estás viendo. Si se debía click-through destino para este clip, ClipEventArgs.ClipContext.ClipInformation.ClickThroughUrl lo expone y puede utilizar una técnica de su elección (como interactuar con el explorador para abrir una ventana emergente) para abrir el recurso Web destinado al hacer clic en - a través de la dirección URL.

También puede utilizar el evento ClipError y el evento ClipStateChanged para manejar cualquier las condiciones de error y los cambios de estado para el clip, respectivamente. 

Velocidad de reproducción y dirección

SSME permite contenido reproducción a velocidad variable y dirección. La propiedad SmoothStreamingMediaElement.SupportedPlaybackRates devuelve una lista de las velocidades de reproducción admitidos como valores double donde 1.0 indica la velocidad de reproducción predeterminado. En su versión beta pública, esta lista contiene los valores adicionales de 0,5, 4.0, 8.0,-4.0 y-8.0. Los valores positivos habilitar la reproducción en la mitad, 4 x y 8 x velocidades y los valores negativos permiten reproducción inversa (rebobinar) en 4 x y 8 x velocidades.

El método SmoothStreamingMediaElement.SetPlaybackRate se puede llamar para establecer la velocidad de reproducción en cualquier momento durante la reproducción. SetPlaybackRate acepta la velocidad de reproducción que desee como su único parámetro.

Tenga en cuenta que controlar la velocidad de reproducción sólo funciona para Smooth Streaming de contenido, por lo que si utiliza SSME para reproducir contenido que se está descargando progresivamente o transmitido por secuencias mediante algunos otro técnica, SetPlaybackRate provocará una excepción.

Stream suave ediciones utilizar manifiestos compuesto

A veces es posible que deba combinar partes desde varias presentaciones Smooth Streaming en una única presentación compuesta. El escenario más común utiliza herramientas como editores rough-cut que permiten a los usuarios especificar puntos de tiempo de Mark y lMark de salida en un origen principal de producir clips y teniendo varios tales clips desde reproducción potencialmente diferentes orígenes principales de forma lineal como una única presentación.

La característica de manifiesto compuesto de SSME permite realizar esto mediante la creación de un documento independiente de manifiesto que contiene los segmentos de clip, donde cada segmento del clip define una parte de una presentación completa, delimitada por los puntos de tiempo inicial y final del clip. La mayor ventaja de utilizar este enfoque es la capacidad de crear ediciones distintas en presentaciones existentes sin necesidad de transcodificar el material de origen.

Un manifiesto compuesto siempre termina con .csm extensión. Para consumir un manifiesto de tal simplemente establece la SmoothStreamingSource propiedad en una dirección URL válida que señala a un archivo de manifiesto compuesto:

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

Figura 11 muestra un extracto de un manifiesto compuesto. (Todo el archivo se incluye en el descargar código en este artículo).

Figura 11 del manifiesto compuesto de ejemplo

<?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>

Este manifiesto contiene dos elementos de imagen, cada definición de un clip (también denominado una edición) de una presentación existente Smooth Streaming. Los puntos de atributo de dirección URL a una presentación existente Smooth Streaming y los atributos ClipBegin y ClipEnd contienen el comienzo y el final de los valores de tiempo que proporcionan los límites en los que el clip. El atributo de duración en el elemento de nivel superior SmoothStreamingMedia necesita ser la suma exacta de las duraciones de cada clip en el manifiesto, puede sumar la diferencia de los valores de cada entrada de imágenes para obtener la duración total de manifiesto ClipEnd y ClipBegin.

Cada elemento de imagen contiene el vídeo y audio StreamIndex y sus entradas de QualityLevel secundarios, el cliente de la creación de reflejos de manifiesto (.ismc) archivos de las presentaciones de origen. Las entradas de metadatos (c) de fragmento para cada entrada StreamIndex, sin embargo, pueden limitarse a sólo esos fragmentos necesarias para satisfacer los límites ClipBegin y ClipEnd. En otras palabras, el valor ClipBegin debe ser mayor o igual al valor de tiempo (t atributo) de inicio de la primera entrada c de la secuencia y ClipEnd valor debe ser menor o igual a la suma de la hora de inicio y los valores de duración (atributo d) del último movimiento de c para esa secuencia.

Tenga en cuenta que, en el manifiesto del cliente, bloques puede definirse de forma indizada (atributo n) con duraciones especificadas. Sin embargo, el manifiesto de la composición, los fragmentos deben definirse mediante las horas de comienzo (que pueden calcularse fácilmente mediante la suma de las duraciones de los fragmentos anteriores). Tenga en cuenta que el atributo de fragmentos en cada entrada StreamIndex debe reflejar el número de fragmentos en el clip, pero todos los demás atributos reflejan las entradas en el manifiesto del cliente de origen.

Secuencias en directo

SSME puede reproducir secuencias a petición y directo. Para reproducir una Smooth Streaming secuencia de vídeo en directo mediante SSME, puede establecer la propiedad SmoothStreamingSource en SSME a una URL de punto de publicación vivo:

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

Para saber si SSME está reproduciendo una transmisión por secuencias en directo, puede comprobar la propiedad IsLive, que se establece en True si el contenido es un origen en directo y false en caso contrario.

Nota que el programa de instalación y la entrega de Smooth Streaming vídeo en directo requiere una infraestructura especializada. Obtener una explicación detallada de configurar un entorno de servidor de transmisión por secuencias live queda fuera del alcance de este artículo. Puede hacer referencia a los artículos en learn.iis.net/page.aspx/628/live-smooth-streaming/ de para obtener más detalles acerca de cómo configurar IIS Media Services 3.0 para la transmisión por secuencias activas. El artículo en learn.iis.net/page.aspx/620/live-smooth-streaming-for-iis-70---getting-started/ le proporcionará información acerca de cómo configurar una simulación de un entorno vivo de transmisión por secuencias para realizar pruebas.

Conclusión

IIS Smooth Streaming es una plataforma de transmisión por secuencias adaptativa de última generación de Microsoft. Como ha visto, el suavizado PDK transmisión por secuencias (y en particular, el tipo de SmoothStreamingMediaElement) es un ingrediente esencial para la creación de clientes de Silverlight que pueden consumir secuencias a petición y directo. El PDK ofrece un amplio control en el comportamiento de cliente de secuencias suaves y permite escribir a enriquecido y experiencias envolventes que van más allá de secuencias de sólo audio y vídeo, lo que le permite fácilmente combinan secuencias de datos con los medios de forma significativa.

Un tratamiento detallado de Smooth Streaming queda fuera del alcance de este artículo. Le instamos a encontrar más detalles en iis. NET y medios. Para obtener instrucciones más en medio de programación en Silverlight y el tipo de Silverlight MediaElement, puede visitar silverlight.net/getstarted de.

 

Jit Ghosh   es un evangelista arquitecto en el equipo de evangelización de desarrolladores en Microsoft, asesorar a los clientes en la industria de medios en la creación de soluciones de vanguardia de medios digitales. Ghosh es coautor de la libreta de recetas de Silverlight “ ” (APress, 2009). Puede leer su blog en blogs.msdn.com/jitghosh de .

Gracias al siguiente técnico experto para revisar este artículo: Vishal Sood