By using AWS re:Post, you agree to the AWS re:Post Terms of Use

How to make the audio hearable without noise and choppy from amazon connect via kinesis video stream ?

0

Hi Guys,

I'm using kinesis video stream to get the audio stream from the amazon connect interaction with Lex voice bot. I'm using the getmedia API to get the file. But when I tried to convert the pcm file to any format like .wav, .mp3, .mvk etc., I cannot here the audio properly either it is choppy or with so much noisy with extended duration 1minute if the interaction itself is 30 seconds.

I'm trying in java below given the code. Please guide me into this.

public class KinesisAudioToWav {

public static void main(String[] args) {
    Region region = Region.AP_SOUTHEAST_1;
    String streamName = "streamName";

    File rawAudioFile = new File("kinesis_audio_output.pcm");
    boolean isMediaSaved = saveAudioFromKinesis(streamName, region, rawAudioFile);

    if (isMediaSaved) {
        File wavFile = new File("output.wav");
        boolean isConverted = convertPcmToWav(rawAudioFile, wavFile);
        if (isConverted) {
            System.out.println("Successfully converted to: " + wavFile.getAbsolutePath());
        } else {
            System.out.println("Conversion failed.");
        }
    } else {
        System.out.println("Failed to save media from Kinesis.");
    }
}

private static boolean saveAudioFromKinesis(String streamName, Region region, File outputFile) {
	
    String accessKey = "accesskey";
    String secretAccessKey = "secretaccesskey";
    String fragmentNumber = "fragmentNumber";

	AwsCredentialsProvider credentialsProvider = StaticCredentialsProvider.create(
			AwsBasicCredentials.create(accessKey, secretAccessKey));
    try (KinesisVideoClient kinesisVideoClient = KinesisVideoClient.builder().credentialsProvider(credentialsProvider).region(Region.AP_SOUTHEAST_1).build()) {

        GetDataEndpointRequest endpointRequest = GetDataEndpointRequest.builder()
                .streamName(streamName)
                .apiName("GET_MEDIA")
                .build();			
        GetDataEndpointResponse endpointResponse = kinesisVideoClient.getDataEndpoint(endpointRequest);
        
        KinesisVideoMediaClient mediaClient = KinesisVideoMediaClient.builder()
                .endpointOverride(URI.create(endpointResponse.dataEndpoint()))
                .region(Region.AP_SOUTHEAST_1)
                .credentialsProvider(credentialsProvider)
                .build();
        
        GetMediaRequest mediaRequest = GetMediaRequest.builder()
                .streamName(streamName)
                .startSelector(s -> s.startSelectorType("FRAGMENT_NUMBER").afterFragmentNumber(fragmentNumber))
                .build();

        try (ResponseInputStream<GetMediaResponse> mediaResponseStream = mediaClient.getMedia(mediaRequest);
             FileOutputStream fos = new FileOutputStream(outputFile)) {

            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = mediaResponseStream.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
            System.out.println("Audio saved successfully to: " + outputFile.getAbsolutePath());
            return true;

        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

private static boolean convertPcmToWav(File pcmFile, File wavFile) {
    try {

        AudioFormat audioFormat = new AudioFormat(8000, 16, 1, true, false);

        try (InputStream pcmInputStream = new BufferedInputStream(new FileInputStream(pcmFile))) {
            AudioInputStream audioInputStream = new AudioInputStream(pcmInputStream, audioFormat, pcmFile.length() / audioFormat.getFrameSize());

            AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, wavFile);
            System.out.println("WAV file written to: " + wavFile.getAbsolutePath());
            return true;
        }

    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

}

1 Answer
1

To improve the audio quality from Amazon Connect via Kinesis Video Streams and address the issues of noise and choppiness, consider the following adjustments to your approach:

  1. Sampling Rate: Ensure you're using the correct sampling rate. Amazon Connect sends audio to Kinesis Video Streams at 8 kHz. Your code is already using this rate, which is correct.

  2. Bit Depth: The audio from Amazon Connect is likely 16-bit. Your code is already using 16 bits, which is correct.

  3. Channels: Amazon Connect typically uses mono audio. Your code is already set to 1 channel (mono), which is correct.

  4. Fragment Handling: Instead of using a single fragment, consider retrieving multiple fragments to ensure you're getting the complete audio stream. You may need to implement logic to handle multiple fragments and stitch them together.

  5. Audio Format: When converting from PCM to WAV, ensure you're interpreting the raw PCM data correctly. The audio format you're using (8000 Hz, 16-bit, 1 channel, signed, little-endian) seems correct for Amazon Connect audio.

  6. Buffer Size: Consider adjusting the buffer size when reading from the Kinesis stream. A larger buffer might help with smoother playback.

  7. Error Handling: Implement more robust error handling and logging to identify where issues might be occurring in the process.

  8. Kinesis Video Streams SDK: Consider using the Kinesis Video Streams Parser Library, which is designed to handle the complexities of parsing Kinesis Video Streams data.

  9. Timing Information: Kinesis Video Streams includes timing information with each fragment. Use this to ensure proper playback timing and avoid stretching or compressing the audio.

  10. Audio Processing: If noise is still an issue, consider implementing some basic audio processing techniques like noise reduction or normalization after retrieving the audio data.

  11. Testing: Test with different audio samples and durations to ensure your solution works consistently.

If these adjustments don't resolve the issue, you may need to further investigate the raw PCM data you're receiving from Kinesis Video Streams to ensure it's being interpreted correctly during the conversion process.

Sources
Plan for live media streaming from Amazon Connect to Kinesis Video Streams - Amazon Connect
Amazon Kinesis Video Streams Features - Secure Video Ingestion for Analysis & Storage - Amazon Web Services
Consume media data - Amazon Kinesis Video Streams

profile picture
answered 2 months ago
profile picture
EXPERT
reviewed 2 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions