選取您的 Cookie 偏好設定

我們使用提供自身網站和服務所需的基本 Cookie 和類似工具。我們使用效能 Cookie 收集匿名統計資料,以便了解客戶如何使用我們的網站並進行改進。基本 Cookie 無法停用,但可以按一下「自訂」或「拒絕」以拒絕效能 Cookie。

如果您同意,AWS 與經核准的第三方也會使用 Cookie 提供實用的網站功能、記住您的偏好設定,並顯示相關內容,包括相關廣告。若要接受或拒絕所有非必要 Cookie,請按一下「接受」或「拒絕」。若要進行更詳細的選擇,請按一下「自訂」。

檢查程式碼

焦點模式
檢查程式碼 - Amazon Kinesis Video Streams

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

本節您將檢驗 Java 程式庫及測試程式碼,並了解如何在自己的程式碼之中,使用程式庫的各項工具。

Kinesis 影片串流剖析器程式庫包含下列工具:

StreamingMkvReader

此類別會以非封鎖方式從串流讀取指定的MKV元素。

下列程式碼範例 (來自 FragmentMetadataVisitorTest) 顯示如何建立及使用 Streaming MkvReader,由名為 inputStream 的輸入串流擷取 MkvElement 物件。

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

FragmentMetadataVisitor

此類別會擷取片段 (媒體元素) 的中繼資料,並追蹤包含媒體資訊的個別資料串流,例如編解碼器私有資料、像素寬度或像素高度。

下列程式碼範例 (來自 FragmentMetadataVisitorTest 檔案) 顯示如何使用 FragmentMetadataVisitorMkvElement 物件擷取資料:

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

前述範例顯示下列編碼模式:

  • 建立 FragmentMetadataVisitor 剖析資料,以及建立 StreamingMkvReader 提供資料。

  • 對於串流之中的各個 MkvElement,請測試其中繼資料是否為 SIMPLEBLOCK 類型。

  • 如果是,請由 MkvElement 擷取 MkvDataElement

  • MkvDataElement 擷取 Frame (媒體資料)。

  • FragmentMetadataVisitor 擷取 MkvTrackMetadata 用於 Frame

  • FrameMkvTrackMetadata 物件擷取和驗證下列資料:

    • 軌道編號。

    • 影格像素高度。

    • 影格像素寬度。

    • 用於編碼影格轉碼器的轉碼器 ID。

    • 此影格依序抵達。確認前一個影格的追蹤編號,如果有的話,會小於目前影格的追蹤編號。

如欲在專案使用 FragmentMetadataVisitor,請將 MkvElement 物件以其 accept 方式傳送至訪客:

mkvElement.get().accept(fragmentVisitor);

OutputSegmentMerger

此類別將串流之中不同軌道的中繼資料合併,成為單一區段的串流。

下列程式碼範例 (來自 FragmentMetadataVisitorTest 檔案) 顯示如何使用 OutputSegmentMerger,由名為 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); } }

前述範例顯示下列編碼模式:

  • 建立 FragmentMetadataVisitor 由串流擷取中繼資料。

  • 建立輸出串流以接收合併的中繼資料。

  • 建立 OutputSegmentMerger,在 ByteArrayOutputStream 之中傳送。

  • 建立包含兩個訪客的 CompositeMkvElementVisitor

  • 建立 InputStream 指向指定檔案。

  • 將輸入資料的各個元素合併為輸出串流。

KinesisVideoExample

這是示範如何使用 Kinesis 影片串流剖析器程式庫的範例應用程式。

此類別執行下列操作:

  • 建立 Kinesis 影片串流。如果特定名稱串流已經存在,串流將遭到刪除並重新建立。

  • 呼叫 PutMedia將影片片段串流至 Kinesis 影片串流。

  • 從 Kinesis GetMedia 影片串流中串流影片片段的呼叫。

  • 使用 StreamingMkvReader 剖析在串流傳回的片段,並使用 FragmentMetadataVisitor 記錄片段。

刪除及重新建立串流

下列程式碼範例 (從 StreamOps.java 檔案) 會刪除指定的 Kinesis 影片串流:

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

下列程式碼範例 (從 StreamOps.java 檔案) 會建立具有指定名稱的 Kinesis 影片串流:

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

呼叫 PutMedia

下列程式碼範例 (來自 PutMediaWorker.java 檔案) PutMedia呼叫串流:

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

呼叫 GetMedia

串流GetMedia上的下列程式碼範例 (來自 GetMediaWorker.java 檔案) 呼叫:

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

剖析 GetMedia 結果

本節說明如何使用 StreamingMkvReaderFragmentMetadataVisitorCompositeMkvElementVisitor,以剖析、儲存至檔案,以及記錄 GetMedia 傳回的資料。

GetMedia 使用 讀取 的輸出 StreamingMkvReader

下列程式碼範例 (從 GetMediaWorker.java 檔案) 會建立 StreamingMkvReader,並使用它來剖析 GetMedia操作的結果:

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

在前述程式碼範例中,StreamingMkvReaderGetMedia 結果的承載擷取 MKVElement 物件。在下節之中,元素將傳送至 FragmentMetadataVisitor

使用 擷取片段 FragmentMetadataVisitor

下列程式碼範例 (來自 KinesisVideoExample.javaStreamingMkvReader.java 檔案) 建立 FragmentMetadataVisitorMkvElement 物件 (由 StreamingMkvReader 重複執行) 將以 accept 方法傳送至訪客。

來自 KinesisVideoExample.java

FragmentMetadataVisitor fragmentMetadataVisitor = FragmentMetadataVisitor.create();

來自 StreamingMkvReader.java

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

記錄元素並將其寫入檔案

下列程式碼範例 (來自 KinesisVideoExample.java 檔案) 建立下列物件,並將其以 GetMediaProcessingArguments 函數傳回值的一部分傳回:

  • LogVisitor (MkvElementVisitor 延伸) 寫入系統記錄。

  • 將傳入資料OutputStream寫入 MKV 檔案的 。

  • BufferedOutputStream 針對 OutputStream 緩衝資料邊界。

  • OutputSegmentMergerGetMedia結果中的連續元素與相同的軌跡和EBML資料合併。

  • FragmentMetadataVisitorOutputSegmentMerger和 組成LogVisitor單一元素訪客CompositeMkvElementVisitor的 。

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

然後,媒體處理引數會傳遞至 GetMediaWorker,再傳遞至 ExecutorService,而 會在不同的執行緒上執行工作者:

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

下一個主題:

執行程式碼

上一個主題:

下載程式碼
隱私權網站條款Cookie 偏好設定
© 2025, Amazon Web Services, Inc.或其附屬公司。保留所有權利。