Crash on KeplerVideoSurfaceView

:warning: Before you continue


Before submitting a bug report, please review our troubleshooting documentation at Troubleshoot Issues | Vega Troubleshooting

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.


:backhand_index_pointing_right: Bug Description


1. Summary

Player crashes on playing.

App Name: Vix
App Link on Amazon Appstore (found through Developer Console β†’ Actions column in App List β†’ View on Amazon.com):

Bug Severity
Select one that applies

  • 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

  1. Reproduce player. Observe behaviour.

3. Observed Behavior

Explain what actually happened, noting any discrepancies or malfunctions.

Full crash of app. 

4. Expected Behavior

Describe what you expected the SDK to do under normal operation.

Player wont crash.

4.a Possible Root Cause & Temporary Workaround

Fill out anything you have tried. If you don’t know, N/A is acceptable

Nothing.

5. Logs or crash report

(Please make sure to provide relevant logs as attachment)

396#crash_1777188064_30037_5000_330905_451615411_JSThread_235.acr (648.5 KB)

For crash issues, please refer this guide for faster troubleshooting: Detect Where the App Crash Originates | Design and Develop Vega Apps

  • App/Device Logs

  • Crash Logs

  • Crash Report

  • For issues with Vega Studio Extension, please share log files from below folders:
    For v0.22+:

    ~/.vscode/extensions/amazon.vega-extension-<version>/ExtensionLogs
    ~/.vscode/extensions/amazon.vega-ui-extension-<version>/ExtensionLogs
    

    For v0.21 and earlier:

     ~/.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: Run vega --version (v0.22+) or kepler --version (v0.21 and earlier) and paste output

  • Active SDK Version: 0.22.6006

    Vega CLI Version: 1.2.18

  • App State: [Foreground/Background]

  • OS Information: Please ssh into the device via vega exec vda shell (or kepler exec vda shell for v0.21 and earlier) and copy the output from cat /etc/os-release into the answer section below. Note, if you don’t have a simulator running or device attached, the command will respond with vda: no devices/emulators found

    <!-- Answer here if applicable --> 
    

7. Example Code Snippet / Screenshots / Screengrabs

Include any relevant code or component setup in React Native that can help reproduce the bug.

/* eslint-disable jsdoc/require-description */
/* eslint-disable jsdoc/require-param-description */
/* eslint-disable react-native/no-inline-styles */
import React, {
  useCallback, useEffect, useMemo, useRef, useState,
} from 'react';
import { BackHandler, Pressable, View } from 'react-native';
import { useNavigation } from '@amazon-devices/react-navigation__core';
import { VideoPlayer, KeplerVideoSurfaceView } from '@amazon-devices/react-native-w3cmedia';

import Text from 'src/components/atoms/Text/Text';
import getStyles from './PlayerScreenLight.styles';

/**
 * @param seconds
 */
function formatTime(seconds: number): string {
  if (!Number.isFinite(seconds) || seconds < 0) return '0:00';
  const m = Math.floor(seconds / 60);
  const s = Math.floor(seconds % 60);
  return `${m}:${s.toString().padStart(2, '0')}`;
}

/**
 * Player Screen Light component
 */
function PlayerScreenLight(): JSX.Element {
  const styles = useMemo(() => getStyles(), []);
  const navigation = useNavigation();
  const video = useRef<VideoPlayer | null>(null);
  const progressInterval = useRef<ReturnType<typeof setInterval> | null>(null);
  const [isPlaying, setIsPlaying] = useState(false);
  const [currentTime, setCurrentTime] = useState(0);
  const [duration, setDuration] = useState(0);

  // ─── init ─────────────────────────────────────────────────────────────────────
  useEffect(() => {
    const player = new VideoPlayer();
    video.current = player;

    return () => {
      if (progressInterval.current) {
        clearInterval(progressInterval.current);
        progressInterval.current = null;
      }
      player.deinitialize().catch((e) => console.error('Error en deinitialize:', e));
      video.current = null;
    };
  }, []);

  // ─── surface callbacks ────────────────────────────────────────────────────────
  const onSurfaceViewCreated = useCallback(async (surfaceHandle: string) => {
    if (!video.current) return;

    await video.current.initialize();

    video.current.addEventListener('loadedmetadata', () => {
      const dur = video.current?.duration ?? 0;
      if (dur > 0) setDuration(dur);
    });

    video.current.src = 'https://www.w3schools.com/html/mov_bbb.mp4';
    video.current.setSurfaceHandle(surfaceHandle);

    await video.current.play();
    setIsPlaying(true);
    setCurrentTime(0);

    progressInterval.current = setInterval(() => {
      if (!video.current) return;
      setCurrentTime(video.current.currentTime ?? 0);
      const dur = video.current.duration ?? 0;
      if (dur > 0) setDuration(dur);
    }, 500);
  }, []);

  const onSurfaceViewDestroyed = useCallback((_surfaceHandle: string) => {
    video.current?.clearSurfaceHandle(_surfaceHandle);
    if (progressInterval.current) {
      clearInterval(progressInterval.current);
      progressInterval.current = null;
    }
    setIsPlaying(false);
  }, []);

  // ─── controls ────────────────────────────────────────────────────────────────
  const handlePlayPause = useCallback(async () => {
    if (!video.current) return;
    if (isPlaying) {
      video.current.pause();
      setIsPlaying(false);
    } else {
      await video.current.play();
      setIsPlaying(true);
    }
  }, [isPlaying]);

  const handleBackPress = useCallback(() => {
    if (navigation.canGoBack()) navigation.goBack();
  }, [navigation]);

  useEffect(() => {
    const onBackPress = () => { void handleBackPress(); return true; };
    const sub = BackHandler.addEventListener('hardwareBackPress', onBackPress);
    return () => sub.remove();
  }, [handleBackPress]);

  // ─── render ───────────────────────────────────────────────────────────────────
  const progress = duration > 0 ? Math.min(currentTime / duration, 1) : 0;

  return (
    <View style={{ flex: 1, backgroundColor: 'black' }}>
      <KeplerVideoSurfaceView
        style={{ flex: 1 }}
        scalingmode="fit"
        onSurfaceViewCreated={onSurfaceViewCreated}
        onSurfaceViewDestroyed={onSurfaceViewDestroyed}
      />

      <View style={{
        position: 'absolute',
        bottom: 0,
        left: 0,
        right: 0,
        paddingHorizontal: 20,
        paddingBottom: 36,
        paddingTop: 16,
        backgroundColor: 'rgba(0,0,0,0.55)',
      }}>
        {/* Progress bar */}
        <View style={{
          height: 3,
          backgroundColor: 'rgba(255,255,255,0.25)',
          borderRadius: 2,
          marginBottom: 10,
        }}>
          <View style={{
            height: 3,
            width: `${progress * 100}%`,
            backgroundColor: '#fff',
            borderRadius: 2,
          }} />
        </View>

        {/* Time */}
        <View style={{ flexDirection: 'row', justifyContent: 'space-between', marginBottom: 12 }}>
          <Text style={{ color: 'rgba(255,255,255,0.85)', fontSize: 12, fontVariant: ['tabular-nums'] }}>
            {formatTime(currentTime)}
          </Text>
          <Text style={{ color: 'rgba(255,255,255,0.85)', fontSize: 12, fontVariant: ['tabular-nums'] }}>
            {duration > 0 ? formatTime(duration) : '--:--'}
          </Text>
        </View>

        {/* Play/Pause */}
        <View style={{ alignItems: 'center' }}>
          <Pressable
            onPress={handlePlayPause}
            style={({ pressed }) => ({
              width: 56,
              height: 56,
              borderRadius: 28,
              backgroundColor: pressed ? 'rgba(255,255,255,0.9)' : 'rgba(255,255,255,0.75)',
              justifyContent: 'center',
              alignItems: 'center',
            })}
            accessibilityLabel={isPlaying ? 'Pausar video' : 'Reproducir video'}
            accessibilityRole="button"
          >
            <Text style={{ fontSize: 22, color: 'black' }}>
              {isPlaying ? '⏸' : 'β–Ά'}
            </Text>
          </Pressable>
        </View>
      </View>
    </View>
  );
}

export default PlayerScreenLight;     

:backhand_index_pointing_right: Playback Issues


If this is a playback issue, please provide your content URL, any pre-conditions (like geo-location), and let us know if it’s x86 or arm7.


<!-- Describe your playback issue if applicable -->

Please share the following details in addition:_

  • Player SDK: [Bitmovin, Shaka, ...]
  • Player SDK Version: [e.g. 1.23]
    • Audio Codecs: [AAC, ...]
    • Video Codecs: [h.264, mp4]
    • Manifest Types: [m3u8, dash, etc ..]

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

[N/A or Content / Media Url for testing]

Q: Are there any special headers required to reproduce the issue you are facing?

[N/A or Insert Headers]

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 --> 

:backhand_index_pointing_right: 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  --> 

Hi Sofia,

Thank you for the detailed bug report on the KeplerVideoSurfaceView crash issue.

Our team is investigating this and will provide an update as soon as we have more information. In the meantime, could you provide:

  1. Does this crash happen consistently or intermittently?
  2. Does it happen with all video URLs or only specific ones?
  3. Does it happen immediately on play, or after some time?

Thanks for helping us improve the Vega platform.

Warm regards,
Aishwarya

  1. This is happening intermittently. Sometimes at first time, sometimes third time.
  2. All video URLs
  3. It happens only when playing for the first time. Sometimes second time.

Title: Native crash in libW3CMedia.so / libgobject-2.0.so when using KeplerVideoSurfaceView with VideoPlayer

Severity: Critical β€” app crashes on every video playback attempt

Platform: Vega OS 1.1 (VegaMainlineTvIntegration/10209430), aarch64

SDK: @amazon-devices/react-native-w3cmedia


Description

The app consistently crashes with SIGSEGV when using KeplerVideoSurfaceView with VideoPlayer. The crash occurs inside the native SDK stack and cannot be prevented from JavaScript.

Crash reason: SIGSEGV /0x00000000

Crash stack:

0  libgobject-2.0.so.0 + 0x3cb60
1  libgobject-2.0.so.0 + 0x2122c
2  libmediaplayer.so + 0x1ec38
3  libmediaplayer.so + 0x46750
4  libmediaplayer.so + 0x21d48
5  libkepler_media_player.so + 0x115468
6  libW3CMedia.so + 0x92bb84
7  libW3CMedia.so + 0x90a598
8  libW3CMedia.so + 0x8fc140
...

Key register value:

x15 = 0x617453656d61536e  β†’  ASCII: "nSameState"

This indicates a concurrent GStreamer state transition β€” the SDK is attempting to transition a GObject/GStreamer pipeline to a state that is already in progress, causing a use-after-free or invalid state access.


Steps to reproduce

  1. Navigate to a screen containing KeplerVideoSurfaceView

  2. onSurfaceViewCreated fires β€” call initialize(), setSurfaceHandle(), set src, call play()

  3. Navigate away from the screen

  4. Navigate back to the same screen

  5. App crashes on step 2 of the second visit

Minimal reproduction code:

typescript

const onSurfaceViewCreated = async (surfaceHandle: string) => {
  const player = new VideoPlayer();
  await player.initialize();
  player.setSurfaceHandle(surfaceHandle);
  player.src = 'https://www.w3schools.com/html/mov_bbb.mp4';
  await player.play();
};

const onSurfaceViewDestroyed = (_surfaceHandle: string) => {
  video.current?.clearSurfaceHandle(null);
};

// On component unmount:
await player.deinitialize();

Solution was moving to newer SDK.