

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.

# 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);
```