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
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
Essa classe lê MKV elementos especificados de um fluxo de 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
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 para fornecer os dados. -
Em cada
MkvElement
no streaming, teste se os metadados são do tipoSIMPLEBLOCK
. -
Se forem, recupere o
MkvDataElement
doMkvElement
. -
Recupere o
Frame
(dados de mídia) doMkvDataElement
. -
Recupere os
MkvTrackMetadata
doFrame
doFragmentMetadataVisitor
. -
Recupere e verifique os seguintes dados dos objetos
Frame
eMkvTrackMetadata
:-
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
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 FragmentMetadataVisitorpara recuperar os metadados do stream.
-
Criar um streaming de saída para receber os metadados mesclados.
-
Crie um
OutputSegmentMerger
, passando oByteArrayOutputStream
. -
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
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 PutMediapara transmitir fragmentos de vídeo para o stream de vídeo do Kinesis.
-
Chamadas GetMediapara transmitir fragmentos de vídeo do stream de vídeo do Kinesis.
-
Usa uma StreamingMkvReader para analisar os fragmentos retornados no stream, e usa um FragmentMetadataVisitor para registrar os fragmentos.
Excluir e recriar o stream
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
O exemplo de código a seguir (do PutMediaWorker.java
arquivo) faz chamadas PutMediano stream:
putMedia.putMedia(new PutMediaRequest().withStreamName(streamName) .withFragmentTimecodeType(FragmentTimecodeType.RELATIVE) .withProducerStartTimestamp(new Date()) .withPayload(inputStream), new PutMediaAckResponseHandler() { ... });
Ligue GetMedia
O exemplo de código a seguir (do GetMediaWorker.java
arquivo) faz chamadas GetMediano stream:
GetMediaResult result = videoMedia.getMedia(new GetMediaRequest().withStreamName(streamName).withStartSelector(startSelector));
Analise o resultado GetMedia
Esta seção descreve como usar StreamingMkvReader, FragmentMetadataVisitor e CompositeMkvElementVisitor
para analisar, salvar no arquivo e registrar os dados retornados de GetMedia
.
Leia a saída de GetMedia com StreamingMkvReader
O exemplo de código a seguir (do GetMediaWorker.java
arquivo) cria um StreamingMkvReader e o usa para analisar o resultado da GetMediaoperaçã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 recupera objetos MKVElement
da carga do resultado GetMedia
. Na próxima seção, os elementos são passados para um FragmentMetadataVisitor.
Recupere fragmentos com FragmentMetadataVisitor
Os exemplos de código a seguir (dos arquivos KinesisVideoExample.java
e StreamingMkvReader.java
) criam um FragmentMetadataVisitor. Os objetos MkvElement
iteradas pelo StreamingMkvReader 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
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 deMkvElementVisitor
) que grava no log do sistema. -
E
OutputStream
que grava os dados recebidos em um MKV arquivo. -
Um
BufferedOutputStream
que acumula dados delimitados para oOutputStream
. -
E OutputSegmentMerger que mescla elementos consecutivos no
GetMedia
resultado com a mesma faixa e EBML dados. -
Um
CompositeMkvElementVisitor
que compõe oFragmentMetadataVisitor,OutputSegmentMerger, eLogVisitor
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 oGetMediaWorker
, que por sua vez é passado para oExecutorService
, 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);