Examine el código - Amazon Kinesis Video Streams

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

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

Esta clase lee MKV los elementos específicos de una transmisión sin bloqueos.

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

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, 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 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

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 FragmentMetadataVisitorpara 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

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 PutMediapara transmitir fragmentos de vídeo a la transmisión de vídeo de Kinesis.

  • Llamadas GetMediapara transmitir fragmentos de vídeo de la transmisión de vídeo de Kinesis.

  • Utiliza StreamingMkvReader para analizar los fragmentos devueltos de la transmisión y utiliza FragmentMetadataVisitor para registrar los fragmentos.

Eliminación y nueva creación de la transmisión

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

El siguiente ejemplo de código (del PutMediaWorker.java archivo) llama PutMediaa la transmisión:

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

Llama GetMedia

El siguiente ejemplo de código (del GetMediaWorker.java archivo) llama GetMediaa la transmisión:

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

Analiza el GetMedia resultado

En esta sección se describe cómo utilizar StreamingMkvReader, FragmentMetadataVisitor y CompositeMkvElementVisitor para analizar, guardar en archivo y registrar los datos devueltos de GetMedia.

Lea el resultado de GetMedia con StreamingMkvReader

El siguiente ejemplo de código (del GetMediaWorker.java archivo) crea un StreamingMkvReader y lo usa para analizar el resultado de la GetMediaoperació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 recupera objetos MKVElement de la carga del resultado de GetMedia. En la siguiente sección, los elementos se pasan a un FragmentMetadataVisitor.

Recupera fragmentos con FragmentMetadataVisitor

Los siguientes ejemplos de código (de los archivos KinesisVideoExample.java y StreamingMkvReader.java) crean un FragmentMetadataVisitor. A continuación, los objetos MkvElement por los que ha iterado StreamingMkvReader 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

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.

  • Y OutputStream que escribe los datos entrantes en un MKV archivo.

  • Un BufferedOutputStream que almacena en búfer los datos vinculados para OutputStream.

  • Y OutputSegmentMerger que fusiona elementos consecutivos del GetMedia resultado con la misma pista y EBML datos.

  • A CompositeMkvElementVisitor que compone elFragmentMetadataVisitor, y LogVisitor en un único elementoOutputSegmentMerger, 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 laGetMediaWorker, que a su vez pasa a laExecutorService, 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);