Before you continue
Before submitting a bug report, please review our troubleshooting documentation at https://developer.amazon.com/docs/kepler-tv/troubleshoot-overview.html.
If you still want to file a bug report, please make sure to fill in all the details below and provide the necessary information.
NOTE: PLEASE ONLY REPORT A SINGLE BUG USING THIS TEMPLATE.
If you’re experiencing multiple issues, please file a separate report for each.
Bug Description
1. Summary
Using Shaka Player with some streams that have in-band CEA608/708 captions, the Shaka Player TextTrack appears as a text track on VideoPlayer, but there are no cues or activeCues ever added to the track. The same behavior can be seen on web with Shaka 4.8.5 and 4.6.18. This is also an issue on web using Shaka Player 4.8.5.
App Name:
App Link on Amazon Appstore (found through Developer Console → Actions column in App List → View on Amazon.com):
Bug Severity
Select one that applies
x Impacts operation of app
- Blocks current development
- Improvement suggestion
- Issue with documentation (If selected, please share the doc link and describe the issue)
- Other
2. Steps to Reproduce
- Build the Shaka Player reference app: https://developer.amazon.com/docs/kepler-tv/media-player-shaka-player.html.
- Load the test stream.
- Enable the Shaka Player TextTrack.
3. Observed Behavior
Explain what actually happened, noting any discrepancies or malfunctions.
No cues are ever populated.
4. Expected Behavior
Describe what you expected the SDK to do under normal operation.
Cues to be available on the VideoPlayer text track and cuechange events to be fired.
4.a Possible Root Cause & Temporary Workaround
Fill out anything you have tried. If you don’t know, N/A is acceptable
Appears to be a Shaka Player bug, resolved in v4.9.0.
5. Logs or crash report
(Please make sure to provide relevant logs as attachment and share VPKG file with your Amazon contact)
For crash issues, please refer this guide for faster troubleshooting: https://developer.amazon.com/docs/kepler-tv/detect-crash.html.
-
For issues with Kepler Studio Extension, please share log files from below folders:
~/.vscode/extensions/amazon.kepler-extension-<version>/ExtensionLogs ~/.vscode/extensions/amazon.kepler-ui-extension-<version>/ExtensionLogs
6. Environment
Please fill out the fields related to your bug below:
-
SDK Version: 0.20.3207
-
App State:
[Foreground] -
OS Information
Please ssh into the device viakepler exec vda shelland copy the output fromcat /etc/os-releaseinto the answer section below. Note, if you don’t have a simulator running or device attachedkepler exec vda shellwill respond withvda: no devices/emulators foundNAME="OS" OE_VERSION="4.0.0" OS_MAJOR_VERSION="1" OS_MINOR_VERSION="1" RELEASE_ID="2" OS_VERSION="1.1" BRANCH_CODE="VegaMainlineTvIntegration" BUILD_DESC="OS 1.1 (VegaMainlineTvIntegration/4411)" BUILD_FINGERPRINT="4.0.147850.0(3072cab629675a74)/4411N:user-external/release-keys" BUILD_VARIANT="user-external" BUILD_TAGS="release-keys" BUILD_DATE="Thu Aug 14 19:28:37 UTC 2025" BUILD_TIMESTAMP="1755199717" VERSION_NUMBER="201010441150"
7. Example Code Snippet / Screenshots / Screengrabs
Include any relevant code or component setup in React Native that can help reproduce the bug.
This is my updated App.tsx in the Shaka ref player: https://developer.amazon.com/docs/kepler-tv/media-player-shaka-player.html. There is a CC button that when clicked should enable logging of activeCues, but with the test stream none ever appear.
/*
* Copyright (c) 2024 Amazon.com, Inc. or its affiliates. All rights reserved.
*
* PROPRIETARY/CONFIDENTIAL. USE IS SUBJECT TO LICENSE TERMS.
*/
import * as React from 'react';
import {useRef, useState, useEffect} from 'react';
import {
Platform,
useWindowDimensions,
View,
StyleSheet,
TouchableOpacity,
Text,
} from 'react-native';
import {
VideoPlayer,
KeplerVideoSurfaceView,
KeplerCaptionsView,
TextTrack,
} from '@amzn/react-native-w3cmedia';
import {ShakaPlayer, ShakaPlayerSettings} from './shakaplayer/ShakaPlayer';
// set to false if app wants to call play API on video manually
const AUTOPLAY = true;
const DEFAULT_ABR_WIDTH: number = Platform.isTV ? 3840 : 1919;
const DEFAULT_ABR_HEIGHT: number = Platform.isTV ? 2160 : 1079;
const content = [
{
title: 'Video 1',
secure: 'true', // true : Use Secure Video Buffers. false: Use Unsecure Video Buffers.
// uri: 'https://vod-gcs-cedexis.cbsaavideo.com/test/HDR10/1783481_dash/stream.mpd',
uri: 'https://dai.google.com/ssai/event/Sid4xiTQTkCT1SLu6rjUSQ/master.m3u8',
drm_scheme: '', // com.microsoft.playready, com.widevine.alpha
drm_license_uri: '', // DRM License acquisition server URL : needed only if the content is DRM protected
// container: 'FMP4',
},
];
export const App = () => {
const currShakaPlayerSettings = useRef<ShakaPlayerSettings>({
secure: false, // Playback goes through secure or non-secure mode
abrEnabled: true, // Enables Adaptive Bit-Rate (ABR) switching
abrMaxWidth: DEFAULT_ABR_WIDTH, // Maximum width allowed for ABR
abrMaxHeight: DEFAULT_ABR_HEIGHT, // Maximum height allowed for ABR
});
const player = useRef<any>(null);
const videoPlayer = useRef<VideoPlayer | null>(null);
const timeoutHandler = useRef<ReturnType<typeof setTimeout> | null>(null);
const [playerSettings, setPlayerSettings] = useState<ShakaPlayerSettings>(
currShakaPlayerSettings.current,
);
const [buttonPress, setButtonPress] = useState(false);
const [nextContent, setNextContent] = useState({index: 0}); // { index: number }
// Track the nextContent state for re-rendering
const nextContentRef = useRef<number>(0);
// Render in Full screen resolution
const {width: deviceWidth, height: deviceHeight} = useWindowDimensions();
useEffect(() => {
if (nextContent.index !== nextContentRef.current) {
nextContentRef.current = nextContent.index;
// Force Re-rendering of <Video> component.
initializeVideoPlayer();
setNextContent((prev) => {
return {...prev};
});
}
}, [nextContent]);
useEffect(() => {
console.log('app: start AppPreBuffering v13.0');
initializeVideoPlayer();
}, []);
const onEnded = async () => {
console.log('app: onEnded received');
player.current.unload();
player.current = null;
await videoPlayer.current?.deinitialize();
removeEventListeners();
onVideoUnMounted();
setNextContent({index: (nextContent.index + 1) % content.length});
};
const onError = () => {
console.log('app: AppPreBuffering: error event listener called');
};
const setUpEventListeners = (): void => {
console.log('app: setup event listeners');
videoPlayer.current?.addEventListener('ended', onEnded);
videoPlayer.current?.addEventListener('error', onError);
};
const removeEventListeners = (): void => {
console.log('app: remove event listeners');
videoPlayer.current?.removeEventListener('ended', onEnded);
videoPlayer.current?.removeEventListener('error', onError);
};
const initializeVideoPlayer = async () => {
console.log('app: calling initializeVideoPlayer');
videoPlayer.current = new VideoPlayer();
// @ts-ignore
global.gmedia = videoPlayer.current;
await videoPlayer.current.initialize();
setUpEventListeners();
videoPlayer.current!.autoplay = false;
initializeShaka();
};
const onSurfaceViewCreated = (surfaceHandle: string): void => {
console.log('app: surface created');
videoPlayer.current?.setSurfaceHandle(surfaceHandle);
videoPlayer.current?.play();
};
const onSurfaceViewDestroyed = (surfaceHandle: string): void => {
videoPlayer.current?.clearSurfaceHandle(surfaceHandle);
};
const onCaptionViewCreated = (captionsHandle: string): void => {
console.log('app: caption view created');
videoPlayer.current?.setCaptionViewHandle(captionsHandle);
};
const initializeShaka = () => {
console.log('app: in initializePlayer() index = ', nextContent.index);
if (videoPlayer.current !== null) {
player.current = new ShakaPlayer(videoPlayer.current, playerSettings);
}
if (player.current !== null) {
player.current.load(content[nextContent.index], AUTOPLAY);
}
};
const onVideoUnMounted = (): void => {
console.log('app: in onVideoUnMounted');
// @ts-ignore
global.gmedia = null;
videoPlayer.current = null;
};
const onClickCC = () => {
if (videoPlayer.current !== null) {
const tracks = videoPlayer.current.textTracks;
// @ts-ignore
const shakaTextTrack = tracks.find(
(textTrack: TextTrack) => textTrack.label === 'Shaka Player TextTrack',
);
console.log('shakaTextTrack', shakaTextTrack);
if (shakaTextTrack) {
console.log('shakaTextTrack cues', shakaTextTrack.cues);
shakaTextTrack.addEventListener('cuechange', (e: any) => {
console.log('Cue change event', e);
const activeCues = shakaTextTrack.activeCues;
console.log('activeCues', activeCues);
if (activeCues.length > 0) {
const activeCue = activeCues[0];
console.log('Active Cue: ', activeCue.text);
}
});
}
}
};
if (!buttonPress) {
return (
<View style={styles.container}>
<TouchableOpacity
style={styles.button}
onPress={() => {
setButtonPress(true);
}}
hasTVPreferredFocus={true}
activeOpacity={1}>
<Text style={styles.buttonLabel}> Press to Play Video </Text>
</TouchableOpacity>
</View>
);
} else {
return nextContent.index === nextContentRef.current ? (
<View style={styles.container}>
<View style={styles.videoContainer}>
<KeplerVideoSurfaceView
style={styles.surfaceView}
onSurfaceViewCreated={onSurfaceViewCreated}
onSurfaceViewDestroyed={onSurfaceViewDestroyed}
/>
<KeplerCaptionsView
onCaptionViewCreated={onCaptionViewCreated}
style={styles.captionView}
/>
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={onClickCC}>
<Text>CC</Text>
</TouchableOpacity>
</View>
</View>
) : (
<View style={styles.videoContainer} />
);
}
};
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
// backgroundColor: '#283593',
justifyContent: 'center',
alignItems: 'center',
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'center',
paddingVertical: 12,
},
button: {
alignItems: 'center',
backgroundColor: '#303030',
borderColor: 'navy',
borderRadius: 10,
borderWidth: 1,
paddingVertical: 12,
paddingHorizontal: 32,
},
buttonLabel: {
color: 'white',
fontSize: 22,
fontFamily: 'Amazon Ember',
},
videoContainer: {
backgroundColor: 'white',
alignItems: 'stretch',
width: '100%',
height: '100%',
flex: 1,
},
surfaceView: {
width: '100%',
height: '100%',
zIndex: 0,
},
captionView: {
width: '100%',
height: '100%',
top: 0,
left: 0,
position: 'absolute',
backgroundColor: 'transparent',
flexDirection: 'column',
alignItems: 'center',
zIndex: 2,
},
});
Playback Issues
If this is a playback issue, please provide your VPKG and/or content URL, any pre-conditions (like geo-location) [Share privately with your Amazon contact] , and let us know if it’s x86 or arm7.
Text cues not rendered for some in-band caption streams
Please share the following details in addition:_
- Player SDK:
[Shaka] - Player SDK Version:
[4.8.5]- Audio Codecs:
[AAC, ...] - Video Codecs:
[h.264, mp4] - Manifest Types:
[m3u8, dash, etc ..]
- Audio Codecs:
Q: Would you like to be contacted to share your latest VPKG compiled with latest SDK:
Y
Q: VPN or Login needed to verify functionality in VPKG?
N
Q: If applicable, please provide your media/content url
If this is created dynamically, tokenized, etc please provide a way for us to access it
Sent to Amazon contact
Q: Are there any special headers required to reproduce the issue you are facing?
N
Additionally please provide the following if possible
Provide Screenshots / Screengrabs / Logs. Please include as much information as you can that will help debug.
<!-- Answer here if applicable -->
Additional Context
Any Additional Context you would like to provide?
Add any other relevant information, such as recent updates to the SDK, dependencies, or device OS that may affect the bug.
<!-- Answer here if applicable -->