

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Examinez le code
<a name="parser-library-write"></a>

Dans cette section, vous examinez la bibliothèque Java et le code test et apprenez à utiliser les outils de la bibliothèque dans votre propre code.

La bibliothèque d'analyseurs de flux vidéo Kinesis contient les outils suivants :
+ [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>

Cette classe lit les éléments spécifiés MKV à partir d'un flux sans blocage.

L'exemple de code suivant (à partir de `FragmentMetadataVisitorTest`) illustre comment créer et utiliser un `Streaming MkvReader` pour récupérer des objets `MkvElement` à partir d'un flux d'entrée appelé `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>

Cette classe récupère les métadonnées des fragments (éléments multimédias) et suit les flux de données individuels contenant des informations multimédia, telles que les données privées du codec, la largeur des pixels ou la hauteur des pixels. 

L'exemple de code suivant (à partir du fichier `FragmentMetadataVisitorTest`) illustre comment utiliser `FragmentMetadataVisitor` pour récupérer des données à partir d'un objet `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'exemple précédent présente le modèle de codage suivant :
+ Créez un `FragmentMetadataVisitor` pour analyser les données et un [StreamingMkvReader](#parser-library-write-SMSR) pour fournir les données.
+ Pour chaque `MkvElement` dans le flux, testez si ses métadonnées sont de type `SIMPLEBLOCK`.
+ Si c'est le cas, récupérez le `MkvDataElement` à partir de `MkvElement`.
+ Récupérez le `Frame` (données média) à partir de `MkvDataElement`.
+ Récupérez les `MkvTrackMetadata` pour le `Frame` à partir de `FragmentMetadataVisitor`.
+ Récupérez et vérifiez les données suivantes à partir du `Frame` et des objets `MkvTrackMetadata` :
  + Le numéro de suivi.
  + La hauteur de l'image en pixels.
  + La largeur de l'image en pixels.
  + L'ID du codec utilisé pour coder l'image.
  + Cette structure est arrivée en ordre. Vérifiez que le numéro de piste de l'image précédente, s'il est présent, est inférieur à celui de l'image actuelle.

Pour utiliser `FragmentMetadataVisitor` dans votre projet, transmettez les objets `MkvElement` au visiteur à l'aide de leur méthode `accept` :

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

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

Cette classe fusionne des métadonnées à partir de différentes pistes du flux dans un flux avec un seul segment.

L'exemple de code suivant (à partir du fichier `FragmentMetadataVisitorTest`) illustre comment utiliser `OutputSegmentMerger` pour fusionner les métadonnées de suivi à partir d'une matrice à octets appelée `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'exemple précédent présente le modèle de codage suivant :
+ Créez un [FragmentMetadataVisitor](#parser-library-write-FMV)pour extraire les métadonnées du flux.
+ Créer un flux de sortie pour recevoir les métadonnées fusionnées.
+ Créez un `OutputSegmentMerger`en passant dans le `ByteArrayOutputStream`.
+ Créez un `CompositeMkvElementVisitor` qui contient les deux visiteurs. 
+ Créez un `InputStream` qui pointe vers le fichier spécifié.
+ Fusionnez chaque élément des données d'entrée dans le flux de sortie.

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

Il s'agit d'un exemple d'application qui montre comment utiliser la bibliothèque d'analyseur de flux vidéo Kinesis.

Cette classe effectue les opérations suivantes :
+ Crée un flux vidéo Kinesis. S'il existe déjà un flux portant ce nom, le flux est supprimé et recréé.
+ Appels [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html)pour diffuser des fragments vidéo dans le flux vidéo Kinesis.
+ Appels [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)pour diffuser des fragments vidéo à partir du flux vidéo Kinesis.
+ Elle utilise un [StreamingMkvReader](#parser-library-write-SMSR) pour analyser les fragments renvoyés sur le flux et utilise une [FragmentMetadataVisitor](#parser-library-write-FMV) pour consigner les fragments.

### Supprimer et recréer le flux
<a name="parser-library-write-example-create"></a>

L'exemple de code suivant (extrait du `StreamOps.java` fichier) supprime un flux vidéo Kinesis donné :

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

L'exemple de code suivant (extrait du `StreamOps.java` fichier) crée un flux vidéo Kinesis portant le nom spécifié :

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

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

L'exemple de code suivant (extrait du `PutMediaWorker.java` fichier) appelle [PutMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_PutMedia.html)le flux :

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

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

L'exemple de code suivant (extrait du `GetMediaWorker.java` fichier) appelle [GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)le flux :

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

### Analyser le résultat GetMedia
<a name="parser-library-write-example-parse"></a>

Cette section décrit comment utiliser [StreamingMkvReader](#parser-library-write-SMSR), [FragmentMetadataVisitor](#parser-library-write-FMV) et `CompositeMkvElementVisitor` pour analyser, enregistrer dans un fichier et consigner les données renvoyées par `GetMedia`.

#### Lisez le résultat de GetMedia with StreamingMkvReader
<a name="parser-library-write-example-parse-smr"></a>

L'exemple de code suivant (extrait du `GetMediaWorker.java` fichier) crée un [StreamingMkvReader](#parser-library-write-SMSR) et l'utilise pour analyser le résultat de l'[GetMedia](https://docs.aws.amazon.com/kinesisvideostreams/latest/dg/API_dataplane_GetMedia.html)opération :

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

Dans l'exemple de code précédent, l'élément [StreamingMkvReader](#parser-library-write-SMSR) extrait des objets `MKVElement` à partir de la charge utile du résultat de `GetMedia`. Dans la section suivante, les éléments sont transmis à un élément [FragmentMetadataVisitor](#parser-library-write-FMV).

#### Récupérez des fragments avec FragmentMetadataVisitor
<a name="parser-library-write-example-parse-fmv"></a>

Les exemples de code suivants (en provenance des fichiers `KinesisVideoExample.java` et `StreamingMkvReader.java` files) créent un élément [FragmentMetadataVisitor](#parser-library-write-FMV). Les objets `MkvElement` itérés par l'élément [StreamingMkvReader](#parser-library-write-SMSR) sont ensuite transmis au visiteur à l'aide de la méthode `accept`. 

*À partir de `KinesisVideoExample.java` :*

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

*À partir de `StreamingMkvReader.java` :*

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

#### Consigner les éléments et les écrire dans un fichier
<a name="parser-library-write-example-parse-cmev"></a>

L'exemple de code suivant (en provenance du fichier `KinesisVideoExample.java`) crée les objets suivants et les renvoie dans le cadre de la valeur renvoyée par la fonction `GetMediaProcessingArguments` :
+ Un élément `LogVisitor` (une extension de `MkvElementVisitor`) qui écrit des données dans le journal système.
+ Un élément `OutputStream` qui copie les données entrantes dans un fichier MKV.
+ Un élément `BufferedOutputStream` qui met en mémoire tampon les données de `OutputStream`.
+ Un élément [OutputSegmentMerger](#parser-library-write-OSM) qui fusionne les éléments consécutifs dans le résultat de `GetMedia` avec les mêmes données de suivi et EBML.
+ Un `CompositeMkvElementVisitor` qui compose le [FragmentMetadataVisitor](#parser-library-write-FMV)[OutputSegmentMerger](#parser-library-write-OSM), et `LogVisitor` en un seul élément visiteur.

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

Les arguments du traitement multimédia sont ensuite transmis au`GetMediaWorker`, qui est à son tour transmis au`ExecutorService`, qui exécute le travailleur sur un thread distinct :

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