

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

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

Nesta seção, você examinará a biblioteca Java e o código de teste e aprenderá a usar as ferramentas da biblioteca no seu próprio código.

A biblioteca de analisadores de stream de vídeo do Kinesis contém as seguintes ferramentas:
+ [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>

Essa classe lê os elementos do MKV especificados a partir de um streaming em uma forma sem bloqueio.

O exemplo de código a seguir (de `FragmentMetadataVisitorTest`) mostra como criar e usar `Streaming MkvReader` para recuperar `MkvElement` objetos de um streaming de entrada chamado `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>

Essa classe recupera metadados para fragmentos (elementos de mídia) e rastreia fluxos de dados individuais contendo informações de mídia, como dados privados do codec, largura ou altura de pixels. 

O código de exemplo a seguir (do arquivo `FragmentMetadataVisitorTest`) mostra como usar `FragmentMetadataVisitor` para recuperar dados de um 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++;
                    }
                }
            }

        }
```

O exemplo anterior mostra o padrão de codificação a seguir:
+ Crie uma classe `FragmentMetadataVisitor` para analisar os dados e uma [StreamingMkvReader](#parser-library-write-SMSR) para fornecer os dados.
+ Em cada `MkvElement` no streaming, teste se os metadados são do tipo `SIMPLEBLOCK`.
+ Se forem, recupere o `MkvDataElement` do `MkvElement`.
+ Recupere o `Frame` (dados de mídia) do `MkvDataElement`.
+ Recupere os `MkvTrackMetadata` do `Frame` do `FragmentMetadataVisitor`.
+ Recupere e verifique os seguintes dados dos objetos `Frame` e `MkvTrackMetadata`:
  + O número de controle.
  + A altura do pixel de quadros.
  + A profundidade do pixel de quadros.
  + O ID do codec usado para codificar o quadro.
  + Que este quadro foi recebido em ordem. Verifique se o número da faixa do quadro anterior, se presente, é menor que o do quadro atual.

Para usar `FragmentMetadataVisitor` no seu projeto, passe os objetos `MkvElement` para o visitante usando o método `accept`:

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

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

Esta classe combina metadados de diferentes trilhas no streaming em um streaming com um segmento único.

O exemplo de código a seguir (do arquivo `FragmentMetadataVisitorTest`) mostra como usar `OutputSegmentMerger` para mesclar metadados de uma matriz de byte chamada `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);
    }
}
```

O exemplo anterior mostra o padrão de codificação a seguir:
+ Crie um [FragmentMetadataVisitor](#parser-library-write-FMV)para recuperar os metadados do stream.
+ Criar um streaming de saída para receber os metadados mesclados.
+ Crie um `OutputSegmentMerger`, passando o `ByteArrayOutputStream`.
+ Crie um `CompositeMkvElementVisitor` que contenha os dois visitantes. 
+ Crie um `InputStream` que aponte para o arquivo especificado.
+ Mescle cada elemento nos dados de entrada no streaming de saída.

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

Este é um aplicativo de exemplo que mostra como usar a biblioteca de analisadores de stream de vídeo Kinesis.

Essa classe executa as seguintes operações:
+ Cria um stream de vídeo do Kinesis. Se um stream com o nome fornecido já existe, o stream é excluído e recriado.
+ Chamadas [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html)para transmitir fragmentos de vídeo para o stream de vídeo do Kinesis.
+ Chamadas [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)para transmitir fragmentos de vídeo do stream de vídeo do Kinesis.
+ Usa uma [StreamingMkvReader](#parser-library-write-SMSR) para analisar os fragmentos retornados no stream, e usa um [FragmentMetadataVisitor](#parser-library-write-FMV) para registrar os fragmentos.

### Excluir e recriar o stream
<a name="parser-library-write-example-create"></a>

O exemplo de código a seguir (do `StreamOps.java` arquivo) exclui um determinado stream de vídeo do Kinesis:

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

O exemplo de código a seguir (do `StreamOps.java` arquivo) cria um stream de vídeo do Kinesis com o nome especificado:

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

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

O exemplo de código a seguir (do `PutMediaWorker.java` arquivo) faz chamadas [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html)no stream:

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

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

O exemplo de código a seguir (do `GetMediaWorker.java` arquivo) faz chamadas [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)no stream:

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

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

Esta seção descreve como usar [StreamingMkvReader](#parser-library-write-SMSR), [FragmentMetadataVisitor](#parser-library-write-FMV) e `CompositeMkvElementVisitor` para analisar, salvar no arquivo e registrar os dados retornados de `GetMedia`.

#### Leia a saída de GetMedia com StreamingMkvReader
<a name="parser-library-write-example-parse-smr"></a>

O exemplo de código a seguir (do `GetMediaWorker.java` arquivo) cria um [StreamingMkvReader](#parser-library-write-SMSR) e o usa para analisar o resultado da [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)operação:

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

No exemplo de código anterior, o [StreamingMkvReader](#parser-library-write-SMSR) recupera objetos `MKVElement` da carga do resultado `GetMedia`. Na próxima seção, os elementos são passados para um [FragmentMetadataVisitor](#parser-library-write-FMV).

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

Os exemplos de código a seguir (dos arquivos `KinesisVideoExample.java` e `StreamingMkvReader.java`) criam um [FragmentMetadataVisitor](#parser-library-write-FMV). Os objetos `MkvElement` iteradas pelo [StreamingMkvReader](#parser-library-write-SMSR) são passados para o visitante usando o 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 elementos e gravação em um arquivo
<a name="parser-library-write-example-parse-cmev"></a>

O exemplo de código a seguir (do arquivo `KinesisVideoExample.java`) cria os seguintes objetos e os retorna como parte do valor de retorno da função `GetMediaProcessingArguments`:
+ Um `LogVisitor` (uma extensão de `MkvElementVisitor`) que grava no log do sistema.
+ Um `OutputStream` que grava os dados de entrada em um MKV arquivo.
+ Um `BufferedOutputStream` que acumula dados delimitados para o `OutputStream`.
+ Um [OutputSegmentMerger](#parser-library-write-OSM) que combina elementos consecutivos no resultado de `GetMedia` com os mesmos dados de controle e EBML.
+ Um `CompositeMkvElementVisitor` que compõe o[FragmentMetadataVisitor](#parser-library-write-FMV),[OutputSegmentMerger](#parser-library-write-OSM), e `LogVisitor` em um único elemento 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);
```

Os argumentos de processamento de mídia são então passados para o`GetMediaWorker`, que por sua vez é passado para o`ExecutorService`, que executa o trabalhador em um encadeamento separado:

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