Langkah 2: Tulis dan periksa kodenya - Amazon Kinesis Video Streams

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Langkah 2: Tulis dan periksa kodenya

Di bagian ini, Anda memeriksa pustaka Java dan kode pengujian, dan mempelajari cara menggunakan alat dari perpustakaan dalam kode Anda sendiri.

Perpustakaan Parser aliran video Kinesis berisi alat-alat berikut:

StreamingMkvReader

Kelas ini membaca elemen MKV tertentu dari aliran dengan cara non-pemblokiran.

Contoh kode berikut (fromFragmentMetadataVisitorTest) menunjukkan cara membuat dan menggunakan a Streaming MkvReader untuk mengambil MkvElement objek dari aliran input yang disebutinputStream:

StreamingMkvReader mkvStreamReader = StreamingMkvReader.createDefault(new InputStreamParserByteSource(inputStream)); while (mkvStreamReader.mightHaveNext()) { Optional<MkvElement> mkvElement = mkvStreamReader.nextIfAvailable(); if (mkvElement.isPresent()) { mkvElement.get().accept(fragmentVisitor); ... } } }

FragmentMetadataVisitor

Kelas ini mengambil metadata untuk fragmen (elemen media) dan melacak aliran data individual yang berisi informasi media, seperti data pribadi codec, lebar piksel, atau tinggi piksel.

Contoh kode berikut (dari FragmentMetadataVisitorTest file) menunjukkan cara menggunakan FragmentMetadataVisitor untuk mengambil data dari MkvElement objek:

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++; } } } }

Contoh sebelumnya menunjukkan pola pengkodean berikut:

  • Buat a FragmentMetadataVisitor untuk mengurai data, dan a StreamingMkvReader untuk menyediakan data.

  • Untuk masing-masing MkvElement aliran, uji apakah metadatanya bertipe. SIMPLEBLOCK

  • Jika ya, ambil MkvDataElement dari. MkvElement

  • Ambil Frame (data media) dari. MkvDataElement

  • Ambil MkvTrackMetadata untuk Frame dari. FragmentMetadataVisitor

  • Mengambil dan memverifikasi data berikut dari Frame dan MkvTrackMetadata objek:

    • Nomor trek.

    • Tinggi piksel bingkai.

    • Lebar piksel bingkai.

    • ID codec untuk codec yang digunakan untuk menyandikan frame.

    • Bahwa bingkai ini tiba secara berurutan. Verifikasi bahwa nomor trek dari frame sebelumnya, jika ada, kurang dari frame saat ini.

Untuk digunakan FragmentMetadataVisitor dalam proyek Anda, berikan MkvElement objek ke pengunjung menggunakan accept metode mereka:

mkvElement.get().accept(fragmentVisitor);

OutputSegmentMerger

Kelas ini menggabungkan metadata dari trek yang berbeda dalam aliran menjadi aliran dengan segmen tunggal.

Contoh kode berikut (dari FragmentMetadataVisitorTest file) menunjukkan cara menggunakan OutputSegmentMerger untuk menggabungkan metadata track dari array byte yang disebut: 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); } }

Contoh sebelumnya menunjukkan pola pengkodean berikut:

  • Buat a FragmentMetadataVisitor untuk mengambil metadata dari aliran.

  • Buat aliran keluaran untuk menerima metadata gabungan.

  • BuatOutputSegmentMerger, lewat diByteArrayOutputStream.

  • Buat CompositeMkvElementVisitor yang berisi dua pengunjung.

  • Buat InputStream yang menunjuk ke file yang ditentukan.

  • Gabungkan setiap elemen dalam data input ke dalam aliran output.

KinesisVideoExample

Ini adalah contoh aplikasi yang menunjukkan cara menggunakan Kinesis video stream Parser Library.

Kelas ini melakukan operasi berikut:

  • Membuat aliran video Kinesis. Jika aliran dengan nama yang diberikan sudah ada, aliran dihapus dan dibuat ulang.

  • Panggilan PutMediauntuk mengalirkan fragmen video ke aliran video Kinesis.

  • Panggilan GetMediauntuk mengalirkan fragmen video keluar dari aliran video Kinesis.

  • Menggunakan a StreamingMkvReader untuk mengurai fragmen yang dikembalikan pada aliran, dan menggunakan a FragmentMetadataVisitor untuk mencatat fragmen.

Hapus dan buat ulang aliran

Contoh kode berikut (dari StreamOps.java file) menghapus aliran video Kinesis yang diberikan:

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

Contoh kode berikut (dari StreamOps.java file) membuat aliran video Kinesis dengan nama yang ditentukan:

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

Panggilan PutMedia

Contoh kode berikut (dari PutMediaWorker.java file) memanggil PutMediaaliran:

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

Panggilan GetMedia

Contoh kode berikut (dari GetMediaWorker.java file) memanggil GetMediaaliran:

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

Parse hasilnya GetMedia

Bagian ini menjelaskan cara menggunakanStreamingMkvReader, FragmentMetadataVisitor dan CompositeMkvElementVisitor mengurai, menyimpan ke file, dan mencatat data yang dikembalikan. GetMedia

Baca output GetMedia dengan StreamingMkvReader

Contoh kode berikut (dari GetMediaWorker.java file) membuat StreamingMkvReader dan menggunakannya untuk mengurai hasil dari GetMediaoperasi:

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

Dalam contoh kode sebelumnya, StreamingMkvReader mengambil MKVElement objek dari muatan hasil. GetMedia Pada bagian selanjutnya, elemen diteruskan ke aFragmentMetadataVisitor.

Ambil fragmen dengan FragmentMetadataVisitor

Contoh kode berikut (dari KinesisVideoExample.java dan StreamingMkvReader.java file) membuat fileFragmentMetadataVisitor. MkvElementObjek yang diulang oleh kemudian StreamingMkvReader diteruskan ke pengunjung menggunakan accept metode ini.

dariKinesisVideoExample.java:

FragmentMetadataVisitor fragmentMetadataVisitor = FragmentMetadataVisitor.create();

dariStreamingMkvReader.java:

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

Log elemen dan tulis ke file

Contoh kode berikut (dari KinesisVideoExample.java file) membuat objek berikut dan mengembalikannya sebagai bagian dari nilai kembali GetMediaProcessingArguments fungsi:

  • A LogVisitor (perpanjangan dariMkvElementVisitor) yang menulis ke log sistem.

  • An OutputStream yang menulis data yang masuk ke file MKV.

  • A BufferedOutputStream yang menyangga data yang terikat untuk. OutputStream

  • Sebuah OutputSegmentMerger yang menggabungkan elemen berturut-turut dalam GetMedia hasil dengan track yang sama dan data EBML.

  • A CompositeMkvElementVisitor yang menyusunFragmentMetadataVisitor,OutputSegmentMerger, dan LogVisitor menjadi pengunjung elemen tunggal.

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

Argumen pemrosesan media kemudian diteruskan keGetMediaWorker, yang pada gilirannya diteruskan keExecutorService, yang membawa pekerja pada utas terpisah:

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

Langkah selanjutnya

Langkah 3: Jalankan dan verifikasi kode