Kinesis ビデオストリーム データにアクセスする方法 - Amazon Connect

Kinesis ビデオストリーム データにアクセスする方法

Kinesis ビデオストリーム データを操作するには、開発者スキルが必要です。このセクションのステップとコードサンプルを使用して、Kinesis ビデオストリーム に送信されたお客様の音声データを確認します。

サンプルの開始方法

GitHubには、Amazon Connect ライブオーディオストリーミングと Amazon Transcribe を使用するリアルタイムトランスクリプションの使用を開始するのに役立つサンプルプロジェクトがあります。「Amazon Connect Real-time Transcription Lambda」を参照してください。

このプロジェクトでは、コード例と完全に機能する Lambda 機能を提供します。Kinesis ビデオストリーム および Amazon Transcribe を使用して、Amazon Connect 通話のキャプチャと文字起こしを開始するのに役立ちます。

このプロジェクトの Lambda 関数を使用して、以下のような他のソリューションを作成できます。

  • IVR での音声のキャプチャ。

  • エージェントにリアルタイムの文字起こしを提供します。

  • Amazon Connect のボイスメールソリューションを作成する。

独自の実装を構築する

前述のサンプルで提供されているソリューション以外のソリューションを実装することもできます。その場合、このセクションでは、Kinesis ビデオストリーム に対して適切な API 呼び出しを行う方法について説明します。これにより、独自のソリューションを最初から構築できます。

  1. この GitHub ページに移動し、Amazon Connect リアルタイム文字起こし Lambda プロジェクトについてお読みください。

  2. [デプロイ] フォルダを選択し、cloudformation.template をダウンロードします。

  3. 次の Java クラスの例を使用します。このクラスは、AWS SDK for Java で Kinesis ビデオパーサーライブラリ上に構築されています。

    • LMSDemo — は、LMSExample を呼び出すメインメソッドを使用したクラスです。

    • LMSExample— は、Kinesis ビデオストリーム パーサーライブラリで提供される例に似ています。これは、指定されたフラグメント番号で指定された Kinesis ビデオストリーム からメディアを取得します。このコードサンプルには、トラックを分離するフレーム処理が含まれています。

    • LMSFrameProcessor — は、Kinesis ビデオストリーム から指定された出力ストリームにデータを保存するために、LMSExample によって呼び出されます。ファイル出力ストリームを使用して、出力をファイルに保存します。このコードサンプルには、トラックを分離するフレーム処理も含まれています。

  4. Audacity、またはその他のオーディオツールを使用して、16 ビット符号付き PCM モノラル形式の .raw オーディオファイルを読み込みます。

Kinesis ビデオストリーム データにアクセスするためのコードサンプル

LMSDemo.java

package com.amazonaws.kinesisvideo.parser.demo; import com.amazonaws.auth.AWSSessionCredentials; import com.amazonaws.auth.AWSSessionCredentialsProvider; import com.amazonaws.kinesisvideo.parser.examples.LMSExample; import com.amazonaws.regions.Regions; import java.io.FileOutputStream; import java.io.IOException; public class LMSDemo { public static void main(String args[]) throws InterruptedException, IOException { LMSExample example = new LMSExample(Regions.US_WEST_2, "<<StreamName>>", "<<FragmentNumber>>", new AWSSessionCredentialsProvider() { @Override public AWSSessionCredentials getCredentials() { return new AWSSessionCredentials() { @Override public String getSessionToken() { return "<<AWSSessionToken>>"; } @Override public String getAWSAccessKeyId() { return "<<AWSAccessKey>>"; } @Override public String getAWSSecretKey() { return "<<AWSSecretKey>>"; } }; } @Override public void refresh() { } }, new FileOutputStream("<<FileName>>.raw")); example.execute(); } }

LMSExample.java

package com.amazonaws.kinesisvideo.parser.examples; import com.amazonaws.auth.AWSCredentialsProvider; import com.amazonaws.kinesisvideo.parser.ebml.MkvTypeInfos; import com.amazonaws.kinesisvideo.parser.mkv.MkvDataElement; import com.amazonaws.kinesisvideo.parser.mkv.MkvElementVisitException; import com.amazonaws.kinesisvideo.parser.mkv.MkvElementVisitor; import com.amazonaws.kinesisvideo.parser.mkv.MkvEndMasterElement; import com.amazonaws.kinesisvideo.parser.mkv.MkvStartMasterElement; import com.amazonaws.kinesisvideo.parser.utilities.FragmentMetadataVisitor; import com.amazonaws.kinesisvideo.parser.utilities.FrameVisitor; import com.amazonaws.kinesisvideo.parser.utilities.LMSFrameProcessor; import com.amazonaws.regions.Regions; import com.amazonaws.services.kinesisvideo.model.StartSelector; import com.amazonaws.services.kinesisvideo.model.StartSelectorType; import java.io.Closeable; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class LMSExample extends KinesisVideoCommon { private final ExecutorService executorService; private GetMediaProcessingArguments getMediaProcessingArguments; private final StreamOps streamOps; private final OutputStream outputStreamFromCustomer; private final OutputStream outputStreamToCustomer; private final String fragmentNumber; public LMSExample(Regions region, String streamName, String fragmentNumber, AWSCredentialsProvider credentialsProvider, OutputStream outputStreamFromCustomer, OutputStream outputStreamToCustomer) throws IOException { super(region, credentialsProvider, streamName); this.streamOps = new StreamOps(region, streamName, credentialsProvider); this.executorService = Executors.newFixedThreadPool(2); this.outputStreamFromCustomer = outputStreamFromCustomer; this.outputStreamToCustomer = outputStreamToCustomer; this.fragmentNumber = fragmentNumber; } public void execute () throws InterruptedException, IOException { getMediaProcessingArguments = GetMediaProcessingArguments.create(outputStreamFromCustomer, outputStreamToCustomer); try (GetMediaProcessingArguments getMediaProcessingArgumentsLocal = getMediaProcessingArguments) { //Start a GetMedia worker to read and process data from the Kinesis Video Stream. GetMediaWorker getMediaWorker = GetMediaWorker.create(getRegion(), getCredentialsProvider(), getStreamName(), new StartSelector().withStartSelectorType(StartSelectorType.FRAGMENT_NUMBER).withAfterFragmentNumber(fragmentNumber), streamOps.amazonKinesisVideo, getMediaProcessingArgumentsLocal.getFrameVisitor()); executorService.submit(getMediaWorker); //Wait for the workers to finish. executorService.shutdown(); executorService.awaitTermination(120, TimeUnit.SECONDS); if (!executorService.isTerminated()) { System.out.println("Shutting down executor service by force"); executorService.shutdownNow(); } else { System.out.println("Executor service is shutdown"); } } finally { outputStream.close(); } } private static class LogVisitor extends MkvElementVisitor { private final FragmentMetadataVisitor fragmentMetadataVisitor; private LogVisitor(FragmentMetadataVisitor fragmentMetadataVisitor) { this.fragmentMetadataVisitor = fragmentMetadataVisitor; } public long getFragmentCount() { return fragmentCount; } private long fragmentCount = 0; @Override public void visit(MkvStartMasterElement startMasterElement) throws MkvElementVisitException { if (MkvTypeInfos.EBML.equals(startMasterElement.getElementMetaData().getTypeInfo())) { fragmentCount++; System.out.println("Start of segment"); } } @Override public void visit(MkvEndMasterElement endMasterElement) throws MkvElementVisitException { if (MkvTypeInfos.SEGMENT.equals(endMasterElement.getElementMetaData().getTypeInfo())) { System.out.println("End of segment"); } } @Override public void visit(MkvDataElement dataElement) throws MkvElementVisitException { } } private static class GetMediaProcessingArguments implements Closeable { public FrameVisitor getFrameVisitor() { return frameVisitor; } private final FrameVisitor frameVisitor; public GetMediaProcessingArguments(FrameVisitor frameVisitor) { this.frameVisitor = frameVisitor; } public static GetMediaProcessingArguments create(OutputStream outputStreamFromCustomer, OutputStream outputStreamToCustomer) throws IOException { //Fragment metadata visitor to extract Kinesis Video fragment metadata from the GetMedia stream. FragmentMetadataVisitor fragmentMetadataVisitor = FragmentMetadataVisitor.create(); //A visitor used to log as the GetMedia stream is processed. LogVisitor logVisitor = new LogVisitor(fragmentMetadataVisitor); //A composite visitor to encapsulate the three visitors. FrameVisitor frameVisitor = FrameVisitor.create(LMSFrameProcessor.create(outputStreamFromCustomer, outputStreamToCustomer, fragmentMetadataVisitor)); return new GetMediaProcessingArguments(frameVisitor); } @Override public void close() throws IOException { } } }

LMSFrameProcessor.java

package com.amazonaws.kinesisvideo.parser.utilities; import com.amazonaws.kinesisvideo.parser.mkv.Frame; import com.amazonaws.kinesisvideo.parser.utilities.FragmentMetadataVisitor; import com.amazonaws.kinesisvideo.parser.utilities.MkvTrackMetadata; import java.io.IOException; import java.io.OutputStream; import java.nio.ByteBuffer; public class LMSFrameProcessor implements FrameVisitor.FrameProcessor { private OutputStream outputStreamFromCustomer; private OutputStream outputStreamToCustomer; private FragmentMetadataVisitor fragmentMetadataVisitor; protected LMSFrameProcessor(OutputStream outputStreamFromCustomer, OutputStream outputStreamToCustomer, FragmentMetadataVisitor fragmentMetadataVisitor) { this.outputStreamFromCustomer = outputStreamFromCustomer; this.outputStreamToCustomer = outputStreamToCustomer; } public static LMSFrameProcessor create(OutputStream outputStreamFromCustomer, OutputStream outputStreamToCustomer, FragmentMetadataVisitor fragmentMetadataVisitor) { return new LMSFrameProcessor(outputStreamFromCustomer, outputStreamToCustomer, fragmentMetadataVisitor); } @Override public void process(Frame frame, MkvTrackMetadata trackMetadata) { saveToOutPutStream(frame); } private void saveToOutPutStream(final Frame frame) { ByteBuffer frameBuffer = frame.getFrameData(); long trackNumber = frame.getTrackNumber(); MkvTrackMetadata metadata = fragmentMetadataVisitor.getMkvTrackMetadata(trackNumber); String trackName = metadata.getTrackName(); try { byte[] frameBytes = new byte[frameBuffer.remaining()]; frameBuffer.get(frameBytes); if (Strings.isNullOrEmpty(trackName) || "AUDIO_FROM_CUSTOMER".equals(trackName)) { outputStreamFromCustomer.write(frameBytes); } else if ("AUDIO_FROM_CUSTOMER".equals(trackName)) { outputStreamToCustomer.write(frameBytes); } else { // Unknown track name. Not writing to output stream. } } catch (IOException e) { e.printStackTrace(); } } }