

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Esamina il codice
<a name="parser-library-write"></a>

In questa sezione, puoi esaminare la libreria Java, testare il codice e scoprire come utilizzare gli strumenti della libreria nel codice.

La libreria di analisi dei flussi video Kinesis contiene i seguenti strumenti:
+ [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>

Questa classe legge gli elementi MKV specificati da un flusso in modalità senza blocchi.

L'esempio di codice seguente (da `FragmentMetadataVisitorTest`) mostra come creare e utilizzare un `Streaming MkvReader` per recuperare gli oggetti `MkvElement` da un flusso di input chiamato `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>

Questa classe recupera i metadati per i frammenti (elementi multimediali) e tiene traccia dei singoli flussi di dati contenenti informazioni multimediali, come dati privati del codec, larghezza dei pixel o altezza dei pixel. 

L'esempio di codice seguente (dal file `FragmentMetadataVisitorTest`) illustra come utilizzare `FragmentMetadataVisitor` per recuperare i dati da un oggetto `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++;
                    }
                }
            }

        }
```

L'esempio precedente mostra i seguenti modelli di codifica:
+ Creare un `FragmentMetadataVisitor` per analizzare i dati e un [StreamingMkvReader](#parser-library-write-SMSR) per inserire i dati.
+ Per ogni `MkvElement` nel flusso, verificare se i relativi metadati sono di tipo `SIMPLEBLOCK`.
+ Se sì, recuperare il `MkvDataElement` dal `MkvElement`.
+ Recuperate il `Frame` (dati multimediali) dal `MkvDataElement`.
+ Recuperare il `MkvTrackMetadata` relativo al `Frame` dal `FragmentMetadataVisitor`.
+ Recuperare e verificare i dati seguenti dagli oggetti `Frame` e `MkvTrackMetadata`:
  + Il numero di traccia.
  + L'altezza dei pixel del fotogramma.
  + La larghezza dei pixel del fotogramma.
  + L'ID codec relativo al codec utilizzato per la codifica del fotogramma.
  + L'arrivo del fotogramma nell'ordine corretto. Verificate che il numero di traccia del frame precedente, se presente, sia inferiore a quello del frame corrente.

Per utilizzare `FragmentMetadataVisitor` nel progetto, inviare gli oggetti `MkvElement` al visitatore tramite il relativo metodo `accept`:

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

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

Questa classe unisce i metadati di diverse tracce del flusso in un flusso con un singolo segmento.

L'esempio di codice seguente (dal file `FragmentMetadataVisitorTest`) illustra come utilizzare `OutputSegmentMerger` per unire i metadati della traccia da un array di byte chiamato `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);
    }
}
```

L'esempio precedente mostra i seguenti modelli di codifica:
+ Creare un [FragmentMetadataVisitor](#parser-library-write-FMV)per recuperare i metadati dal flusso.
+ Creare un flusso di output per ricevere i metadati uniti.
+ Creare un `OutputSegmentMerger`, tramite l'invio del `ByteArrayOutputStream`.
+ Creare un `CompositeMkvElementVisitor` contenente i due visitatori. 
+ Creare un `InputStream` che punti al file specificato.
+ Unire ciascun elemento nei dati di input nel flusso di output.

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

Questa è un'applicazione di esempio che mostra come utilizzare la libreria di parser di flussi video Kinesis.

Questa classe effettua le seguenti operazioni:
+ Crea un flusso video Kinesis. Se un flusso con il nome specificato è già esistente, tale flusso verrà eliminato e ricreato.
+ Chiamate [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html)per trasmettere frammenti video allo stream video Kinesis.
+ Chiamate [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)per lo streaming di frammenti video dal flusso video di Kinesis.
+ Utilizza un [StreamingMkvReader](#parser-library-write-SMSR) per analizzare i frammenti restituiti sul flusso e un [FragmentMetadataVisitor](#parser-library-write-FMV) per registrare i frammenti.

### Eliminazione e nuova creazione del flusso
<a name="parser-library-write-example-create"></a>

Il seguente esempio di codice (dal `StreamOps.java` file) elimina un determinato flusso video Kinesis:

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

Il seguente esempio di codice (dal `StreamOps.java` file) crea un flusso video Kinesis con il nome specificato:

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

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

Il seguente esempio di codice (dal `PutMediaWorker.java` file) chiama [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html)lo stream:

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

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

Il seguente esempio di codice (dal `GetMediaWorker.java` file) chiama [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)lo stream:

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

### Analizza il risultato GetMedia
<a name="parser-library-write-example-parse"></a>

In questa sezione viene descritto come utilizzare [StreamingMkvReader](#parser-library-write-SMSR), [FragmentMetadataVisitor](#parser-library-write-FMV) e `CompositeMkvElementVisitor` per analizzare, salvare sul file e registrare i dati restituiti da `GetMedia`.

#### Leggi l'output di with GetMedia StreamingMkvReader
<a name="parser-library-write-example-parse-smr"></a>

Il seguente esempio di codice (dal `GetMediaWorker.java` file) crea un file [StreamingMkvReader](#parser-library-write-SMSR) e lo utilizza per analizzare il risultato dell'[GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)operazione:

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

Nell'esempio di codice precedente, il [StreamingMkvReader](#parser-library-write-SMSR) recupera gli oggetti `MKVElement` dal payload dei risultati `GetMedia`. Nella sezione successiva, gli elementi vengono inviati a un [FragmentMetadataVisitor](#parser-library-write-FMV).

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

Gli esempi di codice seguenti (dai file `KinesisVideoExample.java` e `StreamingMkvReader.java`) creano un [FragmentMetadataVisitor](#parser-library-write-FMV). Gli oggetti `MkvElement` iterati dal [StreamingMkvReader](#parser-library-write-SMSR) vengono quindi inviati al visitatore tramite il metodo `accept`. 

*da `KinesisVideoExample.java`:*

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

*da `StreamingMkvReader.java`:*

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

#### Registrazione degli elementi e scrittura in un file
<a name="parser-library-write-example-parse-cmev"></a>

L'esempio di codice seguente (dal file `KinesisVideoExample.java`) crea gli oggetti seguenti e li restituisce come parte del valore restituito della funzione `GetMediaProcessingArguments`:
+ Un `LogVisitor` (un'estensione di `MkvElementVisitor`) che effettua la scrittura nel log di sistema.
+ Un `OutputStream` che scrive i dati in entrata su un file MKV.
+ Un `BufferedOutputStream` che effettua il buffer dei dati associati all'`OutputStream`.
+ Un [OutputSegmentMerger](#parser-library-write-OSM) che unisce gli elementi consecutivi nel risultato `GetMedia` con la stessa traccia e gli stessi dati EBML.
+ Un `CompositeMkvElementVisitor` che compone il [FragmentMetadataVisitor](#parser-library-write-FMV) visitatore[OutputSegmentMerger](#parser-library-write-OSM), e `LogVisitor` in un singolo elemento.

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

Gli argomenti di elaborazione multimediale vengono quindi passati a`GetMediaWorker`, che a sua volta viene passato a`ExecutorService`, che esegue il worker su un thread separato:

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