Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Untersuchen Sie den Code
In diesem Abschnitt prüfen Sie die Java-Bibliothek sowie den Testcode und lernen, wie Sie die Klassen der Bibliothek in eigenem Code verwenden können.
Die Kinesis-Videostream-Parser-Bibliothek enthält die folgenden Tools:
StreamingMkvReader
Diese Klasse liest bestimmte MKV-Elemente aus einem Stream blockierungsfrei.
Das folgende Beispiel (aus der Datei FragmentMetadataVisitorTest
) zeigt, wie Sie ein Streaming MkvReader
-Objekt erstellen und verwenden können, um MkvElement
-Objekte aus dem Eingabe-Stream inputStream
zu extrahieren:
StreamingMkvReader mkvStreamReader = StreamingMkvReader.createDefault(new InputStreamParserByteSource(inputStream)); while (mkvStreamReader.mightHaveNext()) { Optional<MkvElement> mkvElement = mkvStreamReader.nextIfAvailable(); if (mkvElement.isPresent()) { mkvElement.get().accept(fragmentVisitor); ... } } }
FragmentMetadataVisitor
Diese Klasse ruft Metadaten für Fragmente (Medienelemente) ab und verfolgt einzelne Datenströme, die Medieninformationen wie private Codec-Daten, Pixelbreite oder Pixelhöhe enthalten.
Das folgende Codebeispiel (aus der Datei FragmentMetadataVisitorTest
) zeigt, wie Sie mit FragmentMetadataVisitor
Daten aus einem MkvElement
-Objekt auslesen können:
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++; } } } }
Das vorhergehende Beispiel weist folgendes Codierungsmuster auf:
-
Ein
FragmentMetadataVisitor
-Objekt wird zum Analysieren der Daten und ein StreamingMkvReader-Objekt zum Bereitstellen der Daten erstellt. -
Bei jedem
MkvElement
im Stream wird geprüft, ob dessen Metadaten den TypSIMPLEBLOCK
haben. -
Ist dies der Fall, wird das
MkvDataElement
aus demMkvElement
abgerufen. -
Das
Frame
-Objekt (Mediendaten) wird ausMkvDataElement
abgerufen. -
Das
MkvTrackMetadata
-Element desFrame
-Objekts wird aus demFragmentMetadataVisitor
-Objekt abgerufen. -
Die folgenden Daten werden aus den
Frame
- undMkvTrackMetadata
-Objekten abgerufen und geprüft:-
Track-Nummer
-
Framehöhe in Pixeln
-
Framebreite in Pixeln
-
ID des zur Codierung des Frames verwendeten Codecs
-
Richtige Position des Frames im Stream. Stellen Sie sicher, dass die Titelnummer des vorherigen Frames, falls vorhanden, kleiner ist als die des aktuellen Frames.
-
Um FragmentMetadataVisitor
im Projekt zu verwenden, übergeben Sie MkvElement
-Objekte mit deren accept
-Methode an das Visitor-Objekt:
mkvElement.get().accept(fragmentVisitor);
OutputSegmentMerger
Diese Klasse führt die Metadaten verschiedener Tracks im Stream zu einem Stream mit einem einzigen Segment zusammen.
Das folgende Codebeispiel (aus der Datei FragmentMetadataVisitorTest
) zeigt, wie Sie mit einem OutputSegmentMerger
-Objekt die Track-Metadaten im Byte-Array inputBytes
zusammenführen:
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); } }
Das vorhergehende Beispiel weist folgendes Codierungsmuster auf:
-
Erstellen Sie FragmentMetadataVisitor, um die Metadaten aus dem Stream abzurufen.
-
Ein Ausgabe-Stream für die zusammengeführten Metadaten wird erstellt.
-
Erstellen Sie
OutputSegmentMerger
, übergeben Sie dabeiByteArrayOutputStream
. -
Erstellen Sie das
CompositeMkvElementVisitor
-Objekt, das die beiden Besucher enthält. -
Erstellen Sie einen
InputStream
, der auf die angegebene Datei zeigt. -
Die einzelnen Elemente in den Eingabedaten werden im Ausgabe-Stream zusammengeführt.
KinesisVideoExample
Dies ist eine Beispielanwendung, die zeigt, wie die Kinesis-Videostream-Parser-Bibliothek verwendet wird.
Diese Klasse führt die folgenden Operationen aus:
-
Erzeugt einen Kinesis-Videostream. Wenn ein Stream mit dem angegebenen Namen bereits vorhanden ist, wird der Stream gelöscht und neu erstellt.
-
Aufrufe PutMediazum Streamen von Videofragmenten in den Kinesis-Videostream.
-
Aufrufe GetMediazum Streamen von Videofragmenten aus dem Kinesis-Videostream.
-
Verwendet einen StreamingMkvReader zum Analysieren der zurückgegebenen Fragmente auf dem Stream und verwendet FragmentMetadataVisitor für die Protokollierung der Fragmente.
Löschen und Neuerstellen des Streams
Das folgende Codebeispiel (aus der StreamOps.java
Datei) löscht einen bestimmten Kinesis-Videostream:
//Delete the stream amazonKinesisVideo.deleteStream(new DeleteStreamRequest().withStreamARN(streamInfo.get().getStreamARN()));
Das folgende Codebeispiel (aus der StreamOps.java
Datei) erstellt einen Kinesis-Videostream mit dem angegebenen Namen:
amazonKinesisVideo.createStream(new CreateStreamRequest().withStreamName(streamName) .withDataRetentionInHours(DATA_RETENTION_IN_HOURS) .withMediaType("video/h264"));
Rufen Sie an PutMedia
Das folgende Codebeispiel (aus der PutMediaWorker.java
Datei) ruft den Stream PutMediaauf:
putMedia.putMedia(new PutMediaRequest().withStreamName(streamName) .withFragmentTimecodeType(FragmentTimecodeType.RELATIVE) .withProducerStartTimestamp(new Date()) .withPayload(inputStream), new PutMediaAckResponseHandler() { ... });
Rufen Sie GetMedia
Das folgende Codebeispiel (aus der GetMediaWorker.java
Datei) ruft den Stream GetMediaauf:
GetMediaResult result = videoMedia.getMedia(new GetMediaRequest().withStreamName(streamName).withStartSelector(startSelector));
Analysieren Sie das Ergebnis GetMedia
Dieser Abschnitt beschreibt, wie StreamingMkvReader, FragmentMetadataVisitor und CompositeMkvElementVisitor
zur Analyse, zum Speichern in die Datei und zur Protokollierung der von GetMedia
zurückgegebenen Daten verwendet wird.
Lesen Sie die Ausgabe von mit GetMedia StreamingMkvReader
Das folgende Codebeispiel (aus der GetMediaWorker.java
Datei) erstellt eine StreamingMkvReader und verwendet sie, um das Ergebnis der GetMediaOperation zu analysieren:
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); }
Im vorigen Codebeispiel ruft der StreamingMkvReader MKVElement
-Objekte aus der Nutzlast des Ergebnisses von GetMedia
ab. Im nächsten Abschnitt werden die Elemente einem FragmentMetadataVisitor übergeben.
Fragmente abrufen mit FragmentMetadataVisitor
Die folgenden Codebeispiele (aus den Dateien KinesisVideoExample.java
und StreamingMkvReader.java
) erstellen einen FragmentMetadataVisitor. Die MkvElement
-Objekte, die von dem StreamingMkvReader durchlaufen werden, werden dann über die Methode accept
dem Besucher übergeben.
von KinesisVideoExample.java
:
FragmentMetadataVisitor fragmentMetadataVisitor = FragmentMetadataVisitor.create();
von StreamingMkvReader.java
:
if (mkvElementOptional.isPresent()) { //Apply the MkvElement to the visitor mkvElementOptional.get().accept(elementVisitor); }
Die Elemente schreiben und in eine Datei schreiben
Das folgende Code-Beispiel (aus der KinesisVideoExample.java
-Datei) erstellt die folgenden Objekte und gibt sie als Teil des Rückgabewerts der GetMediaProcessingArguments
-Funktion zurück:
-
Einen
LogVisitor
(eine Erweiterung vonMkvElementVisitor
), die in das Systemprotokoll schreibt. -
Einen
OutputStream
, der die eingehenden Daten in eine MKV-Datei schreibt. -
Einen
BufferedOutputStream
, der die fürOutputStream
gebundenen Daten puffert. -
Einen OutputSegmentMerger, der aufeinanderfolgende Elemente in das
GetMedia
-Ergebnis einfügt, mit denselben Track- und EBML-Daten. -
A
CompositeMkvElementVisitor
, das das FragmentMetadataVisitorOutputSegmentMerger, und zu einem einzigen Element zusammensetzt,LogVisitor
den Besucher.
//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);
Die Argumente für die Medienverarbeitung werden dann an den übergebenGetMediaWorker
, der wiederum an den übergeben wirdExecutorService
, der den Worker in einem separaten Thread ausführt:
GetMediaWorker getMediaWorker = GetMediaWorker.create(getRegion(), getCredentialsProvider(), getStreamName(), new StartSelector().withStartSelectorType(StartSelectorType.EARLIEST), amazonKinesisVideo, getMediaProcessingArgumentsLocal.getMkvElementVisitor()); executorService.submit(getMediaWorker);