

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Vea la salida de las cámaras mediante la biblioteca de analizadores
<a name="parser-library"></a>

La biblioteca de analizadores de transmisión de vídeo de Kinesis es un conjunto de herramientas que puede utilizar en aplicaciones Java para consumir los datos MKV de una transmisión de vídeo de Kinesis.

La biblioteca incluye las siguientes herramientas:
+ [StreamingMkvReader](parser-library-write.md#parser-library-write-SMSR): esta clase lee elementos MKV especificados a partir de una transmisión de vídeo.
+ [FragmentMetadataVisitor](parser-library-write.md#parser-library-write-FMV): esta clase recupera los metadatos de fragmentos (elementos multimedia) y pistas (transmisiones de datos individuales que contienen información de medios, como audio o subtítulos).
+ [OutputSegmentMerger](parser-library-write.md#parser-library-write-OSM): esta clase combina fragmentos consecutivos de una transmisión de vídeo.
+ [KinesisVideoExample](parser-library-write.md#parser-library-write-example): Esta es una aplicación de ejemplo que muestra cómo utilizar la biblioteca de analizadores de transmisiones de vídeo de Kinesis.

La biblioteca incluye también pruebas que muestran cómo se utilizan las herramientas.

## Requisitos previos
<a name="parser-library-prerequisites"></a>

Debe disponer de lo siguiente para examinar y utilizar la biblioteca de analizadores de transmisiones de vídeo de Kinesis:
+ Una cuenta de Amazon Web Services (AWS). Si aún no tiene una Cuenta de AWS, consulte[Inscríbase en una Cuenta de AWS](gs-account.md#sign-up-for-aws).
+ Un entorno de desarrollo integrado (IDE) de Java, como [Eclipse Java Neon](https://www.eclipse.org/downloads/packages/release/neon/3/eclipse-jee-neon-3) o [JetBrains IntelliJ Idea](https://www.jetbrains.com/idea/download/).
+ Java 11, como [Amazon Corretto](https://docs.aws.amazon.com//corretto/latest/corretto-11-ug/what-is-corretto-11.html) 11.

# Descarga el código
<a name="parser-library-download"></a>

En esta sección, descargará la biblioteca de Java y el código de prueba, e importará el proyecto en su IDE Java.

Para comprobar los requisitos previos y otros detalles de este procedimiento, consulte [Vea la salida de las cámaras mediante la biblioteca de analizadores](parser-library.md).

1. Cree un directorio y clone el código fuente de la biblioteca desde el GitHub repositorio ([https://github.com/aws/amazon-kinesis-video-streams-parser-library](https://github.com/aws/amazon-kinesis-video-streams-parser-library)). 

   ```
   git clone https://github.com/aws/amazon-kinesis-video-streams-parser-library
   ```

1. Abra el IDE de Java que esté utilizando (por ejemplo, [Eclipse](https://www.eclipse.org/) o [IntelliJ](https://www.jetbrains.com/idea/) IDEA) e importe el proyecto Apache Maven que ha descargado: 
   + **En Eclipse:** seleccione **File**, **Import...**, **Maven**, **Existing Maven Projects** y vaya a la carpeta `kinesis-video-streams-parser-lib`.
   + **En IntelliJ Idea: **seleccione **Import**. Vaya al archivo **pom.xml** en la raíz del paquete descargado.

    Para obtener más información, consulte la documentación del IDE relacionada.

# Examine el código
<a name="parser-library-write"></a>

En esta sección, puede examinar la biblioteca de Java y el código de prueba y aprender a utilizar las herramientas de la biblioteca en su propio código.

La biblioteca del analizador de transmisiones de vídeo de Kinesis contiene las siguientes herramientas:
+ [StreamingMkvReader](#parser-library-write-SMSR)
+ [FragmentMetadataVisitor](#parser-library-write-FMV)
+ [OutputSegmentMerger](#parser-library-write-OSM)
+ [KinesisVideoExample](#parser-library-write-example)

## StreamingMkvReader
<a name="parser-library-write-SMSR"></a>

Esta clase lee elementos MKV especificados de una transmisión sin generar ningún bloqueo.

El siguiente ejemplo de código (de `FragmentMetadataVisitorTest`) muestra cómo crear y utilizar un `Streaming MkvReader` para recuperar objetos `MkvElement` de una transmisión de entrada llamada `inputStream`:

```
StreamingMkvReader mkvStreamReader =
                StreamingMkvReader.createDefault(new InputStreamParserByteSource(inputStream));
        while (mkvStreamReader.mightHaveNext()) {
            Optional<MkvElement> mkvElement = mkvStreamReader.nextIfAvailable();
            if (mkvElement.isPresent()) {
                mkvElement.get().accept(fragmentVisitor);
                ...
                }
            }
        }
```

## FragmentMetadataVisitor
<a name="parser-library-write-FMV"></a>

Esta clase recupera los metadatos de los fragmentos (elementos multimedia) y rastrea los flujos de datos individuales que contienen información multimedia, como los datos privados del códec o el ancho o la altura de los píxeles. 

El siguiente ejemplo de código (del archivo `FragmentMetadataVisitorTest`) muestra cómo utilizar `FragmentMetadataVisitor` para recuperar datos de un objeto `MkvElement`:

```
FragmentMetadataVisitor fragmentVisitor = FragmentMetadataVisitor.create();
        StreamingMkvReader mkvStreamReader =
                StreamingMkvReader.createDefault(new InputStreamParserByteSource(in));
        int segmentCount = 0;
        while(mkvStreamReader.mightHaveNext()) {
            Optional<MkvElement> mkvElement = mkvStreamReader.nextIfAvailable();
            if (mkvElement.isPresent()) {
                mkvElement.get().accept(fragmentVisitor);
                if (MkvTypeInfos.SIMPLEBLOCK.equals(mkvElement.get().getElementMetaData().getTypeInfo())) {
                    MkvDataElement dataElement = (MkvDataElement) mkvElement.get();
                    Frame frame = ((MkvValue<Frame>)dataElement.getValueCopy()).getVal();
                    MkvTrackMetadata trackMetadata = fragmentVisitor.getMkvTrackMetadata(frame.getTrackNumber());
                    assertTrackAndFragmentInfo(fragmentVisitor, frame, trackMetadata);
                }
                if (MkvTypeInfos.SEGMENT.equals(mkvElement.get().getElementMetaData().getTypeInfo())) {
                    if (mkvElement.get() instanceof MkvEndMasterElement) {
                        if (segmentCount < continuationTokens.size()) {
                            Optional<String> continuationToken = fragmentVisitor.getContinuationToken();
                            Assert.assertTrue(continuationToken.isPresent());
                            Assert.assertEquals(continuationTokens.get(segmentCount), continuationToken.get());
                        }
                        segmentCount++;
                    }
                }
            }

        }
```

El ejemplo anterior muestra el siguiente patrón de codificación:
+ Cree una clase `FragmentMetadataVisitor` para analizar los datos y una clase [StreamingMkvReader](#parser-library-write-SMSR) para proporcionar los datos.
+ Para cada `MkvElement` de la transmisión, pruebe si sus metadatos son del tipo `SIMPLEBLOCK`.
+ En caso afirmativo, recupere el `MkvDataElement` del `MkvElement`.
+ Recupere el `Frame` (datos multimedia) del `MkvDataElement`.
+ Recupere los `MkvTrackMetadata` para el `Frame` del `FragmentMetadataVisitor`.
+ Recupere y compruebe los siguientes datos de los objetos `Frame` y `MkvTrackMetadata`:
  + El número de pista.
  + La altura en píxeles del fotograma.
  + La anchura en píxeles del fotograma.
  + El ID del códec para el códec que utilice para codificar el fotograma.
  + Que el fotograma haya llegado en orden. Compruebe que el número de pista del fotograma anterior, si está presente, sea inferior al del fotograma actual.

Para utilizar `FragmentMetadataVisitor` en su proyecto, transfiera los objetos `MkvElement` al visitante con su método `accept`:

```
mkvElement.get().accept(fragmentVisitor);
```

## OutputSegmentMerger
<a name="parser-library-write-OSM"></a>

Esta clase reúne los metadatos de diferentes pistas en la transmisión en una transmisión con un único segmento.

El siguiente ejemplo de código (del archivo `FragmentMetadataVisitorTest`) muestra cómo utilizar `OutputSegmentMerger` para combinar metadatos de pistas a partir de una matriz de bytes denominada `inputBytes`:

```
FragmentMetadataVisitor fragmentVisitor = FragmentMetadataVisitor.create();

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

OutputSegmentMerger outputSegmentMerger =
    OutputSegmentMerger.createDefault(outputStream);

CompositeMkvElementVisitor compositeVisitor =
    new TestCompositeVisitor(fragmentVisitor, outputSegmentMerger);

final InputStream in = TestResourceUtil.getTestInputStream("output_get_media.mkv");

StreamingMkvReader mkvStreamReader =
    StreamingMkvReader.createDefault(new InputStreamParserByteSource(in));
    
while (mkvStreamReader.mightHaveNext()) {
    Optional<MkvElement> mkvElement = mkvStreamReader.nextIfAvailable();
    if (mkvElement.isPresent()) {
        mkvElement.get().accept(compositeVisitor);
    if (MkvTypeInfos.SIMPLEBLOCK.equals(mkvElement.get().getElementMetaData().getTypeInfo())) {
        MkvDataElement dataElement = (MkvDataElement) mkvElement.get();
        Frame frame = ((MkvValue<Frame>) dataElement.getValueCopy()).getVal();
        Assert.assertTrue(frame.getFrameData().limit() > 0);
        MkvTrackMetadata trackMetadata = fragmentVisitor.getMkvTrackMetadata(frame.getTrackNumber());
        assertTrackAndFragmentInfo(fragmentVisitor, frame, trackMetadata);
    }
}
```

El ejemplo anterior muestra el siguiente patrón de codificación:
+ Cree una [FragmentMetadataVisitor](#parser-library-write-FMV)para recuperar los metadatos de la secuencia.
+ Cree una transmisión de salida para recibir los metadatos combinados.
+ Cree un `OutputSegmentMerger`, transfiriendo el `ByteArrayOutputStream`.
+ Cree un `CompositeMkvElementVisitor` que contenga los dos visitantes. 
+ Cree un `InputStream` que apunte al archivo especificado.
+ Combine cada elemento de los datos de entrada en la transmisión de salida.

## KinesisVideoExample
<a name="parser-library-write-example"></a>

Esta es una aplicación de ejemplo que muestra cómo utilizar la biblioteca de analizadores de transmisión de vídeo de Kinesis.

Esta clase realiza las operaciones siguientes:
+ Crea una transmisión de vídeo de Kinesis. Si ya existe una transmisión con ese nombre, se elimina y se vuelve a crear.
+ Llamadas [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html)para transmitir fragmentos de vídeo a la transmisión de vídeo de Kinesis.
+ Llamadas [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)para transmitir fragmentos de vídeo de la transmisión de vídeo de Kinesis.
+ Utiliza [StreamingMkvReader](#parser-library-write-SMSR) para analizar los fragmentos devueltos de la transmisión y utiliza [FragmentMetadataVisitor](#parser-library-write-FMV) para registrar los fragmentos.

### Eliminación y nueva creación de la transmisión
<a name="parser-library-write-example-create"></a>

El siguiente ejemplo de código (del `StreamOps.java` archivo) elimina una transmisión de vídeo de Kinesis determinada:

```
//Delete the stream
amazonKinesisVideo.deleteStream(new DeleteStreamRequest().withStreamARN(streamInfo.get().getStreamARN()));
```

El siguiente ejemplo de código (del `StreamOps.java` archivo) crea una transmisión de vídeo de Kinesis con el nombre especificado:

```
amazonKinesisVideo.createStream(new CreateStreamRequest().withStreamName(streamName)
.withDataRetentionInHours(DATA_RETENTION_IN_HOURS)
.withMediaType("video/h264"));
```

### Llama PutMedia
<a name="parser-library-write-example-putmedia"></a>

El siguiente ejemplo de código (del `PutMediaWorker.java` archivo) llama [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html)a la transmisión:

```
 putMedia.putMedia(new PutMediaRequest().withStreamName(streamName)
.withFragmentTimecodeType(FragmentTimecodeType.RELATIVE)
.withProducerStartTimestamp(new Date())
.withPayload(inputStream), new PutMediaAckResponseHandler() {
...
});
```

### Llama GetMedia
<a name="parser-library-write-example-getmedia"></a>

El siguiente ejemplo de código (del `GetMediaWorker.java` archivo) llama [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)a la transmisión:

```
GetMediaResult result = videoMedia.getMedia(new GetMediaRequest().withStreamName(streamName).withStartSelector(startSelector));
```

### Analiza el GetMedia resultado
<a name="parser-library-write-example-parse"></a>

En esta sección se describe cómo utilizar [StreamingMkvReader](#parser-library-write-SMSR), [FragmentMetadataVisitor](#parser-library-write-FMV) y `CompositeMkvElementVisitor` para analizar, guardar en archivo y registrar los datos devueltos de `GetMedia`.

#### Lea el resultado de GetMedia con StreamingMkvReader
<a name="parser-library-write-example-parse-smr"></a>

El siguiente ejemplo de código (del `GetMediaWorker.java` archivo) crea un [StreamingMkvReader](#parser-library-write-SMSR) y lo usa para analizar el resultado de la [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)operación:

```
StreamingMkvReader mkvStreamReader = StreamingMkvReader.createDefault(new InputStreamParserByteSource(result.getPayload()));
log.info("StreamingMkvReader created for stream {} ", streamName);
try {
    mkvStreamReader.apply(this.elementVisitor);
} catch (MkvElementVisitException e) {
    log.error("Exception while accepting visitor {}", e);
}
```

En el ejemplo de código anterior, [StreamingMkvReader](#parser-library-write-SMSR) recupera objetos `MKVElement` de la carga del resultado de `GetMedia`. En la siguiente sección, los elementos se pasan a un [FragmentMetadataVisitor](#parser-library-write-FMV).

#### Recupera fragmentos con FragmentMetadataVisitor
<a name="parser-library-write-example-parse-fmv"></a>

Los siguientes ejemplos de código (de los archivos `KinesisVideoExample.java` y `StreamingMkvReader.java`) crean un [FragmentMetadataVisitor](#parser-library-write-FMV). A continuación, los objetos `MkvElement` por los que ha iterado [StreamingMkvReader](#parser-library-write-SMSR) se pasan al visitante con el método `accept`. 

*de `KinesisVideoExample.java`:*

```
FragmentMetadataVisitor fragmentMetadataVisitor = FragmentMetadataVisitor.create();
```

*de `StreamingMkvReader.java`:*

```
if (mkvElementOptional.isPresent()) {
    //Apply the MkvElement to the visitor
    mkvElementOptional.get().accept(elementVisitor);
        }
```

#### Registro de los elementos y escritura en un archivo
<a name="parser-library-write-example-parse-cmev"></a>

El siguiente ejemplo de código (del archivo `KinesisVideoExample.java`) crea los siguientes objetos y los devuelve como parte del valor de retorno de la función `GetMediaProcessingArguments`:
+ Un `LogVisitor` (una extensión de `MkvElementVisitor`) que escribe en el log del sistema.
+ Un `OutputStream` que escribe los datos entrantes en un archivo MKV.
+ Un `BufferedOutputStream` que almacena en búfer los datos vinculados para `OutputStream`.
+ Un [OutputSegmentMerger](#parser-library-write-OSM) que fusiona los elementos consecutivos en el resultado de `GetMedia` con los mismos datos de pista y EBML.
+ Un `CompositeMkvElementVisitor` que compone el [FragmentMetadataVisitor](#parser-library-write-FMV)[OutputSegmentMerger](#parser-library-write-OSM), y `LogVisitor` en un único elemento: el visitante.

```
//A visitor used to log as the GetMedia stream is processed.
    LogVisitor logVisitor = new LogVisitor(fragmentMetadataVisitor);

    //An OutputSegmentMerger to combine multiple segments that share track and ebml metadata into one
    //mkv segment.
    OutputStream fileOutputStream = Files.newOutputStream(Paths.get("kinesis_video_example_merged_output2.mkv"),
            StandardOpenOption.WRITE, StandardOpenOption.CREATE);
    BufferedOutputStream outputStream = new BufferedOutputStream(fileOutputStream);
    OutputSegmentMerger outputSegmentMerger = OutputSegmentMerger.createDefault(outputStream);

    //A composite visitor to encapsulate the three visitors.
    CompositeMkvElementVisitor mkvElementVisitor =
            new CompositeMkvElementVisitor(fragmentMetadataVisitor, outputSegmentMerger, logVisitor);

    return new GetMediaProcessingArguments(outputStream, logVisitor, mkvElementVisitor);
```

Luego, los argumentos de procesamiento multimedia se pasan a la`GetMediaWorker`, que a su vez pasa a la`ExecutorService`, que lleva al trabajador a un hilo diferente:

```
GetMediaWorker getMediaWorker = GetMediaWorker.create(getRegion(),
        getCredentialsProvider(),
        getStreamName(),
        new StartSelector().withStartSelectorType(StartSelectorType.EARLIEST),
        amazonKinesisVideo,
        getMediaProcessingArgumentsLocal.getMkvElementVisitor());
executorService.submit(getMediaWorker);
```

# Ejecuta el código
<a name="parser-library-run"></a>

La biblioteca de analizadores de transmisión de vídeo de Kinesis contiene herramientas diseñadas para que las utilice en sus propios proyectos. El proyecto contiene pruebas de unidades de las herramientas que puede ejecutar para verificar su instalación.

Las siguientes pruebas de unidades están incluidas en la biblioteca:
+ **mkv**
  + `ElementSizeAndOffsetVisitorTest`
  + `MkvValueTest`
  + `StreamingMkvReaderTest`
+ **utilidades**
  + `FragmentMetadataVisitorTest`
  + `OutputSegmentMergerTest`