Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App crashing on Firestick #45

Open
hrithvik123 opened this issue Feb 18, 2025 · 0 comments
Open

App crashing on Firestick #45

hrithvik123 opened this issue Feb 18, 2025 · 0 comments

Comments

@hrithvik123
Copy link

hrithvik123 commented Feb 18, 2025

Firestick running fireOS 6.0.7.9 cannot run the app with this plugin on it.

2025-02-17 19:22:43.752 19204-19204 AndroidRuntime app.iptvweb E FATAL EXCEPTION: main Process: app.iptvweb, PID: 19204 java.lang.NoSuchMethodError: No virtual method getMainExecutor()Ljava/util/concurrent/Executor; in class Landroidx/appcompat/app/AppCompatActivity; or its super classes (declaration of 'androidx.appcompat.app.AppCompatActivity' appears in /data/app/app.iptvweb-1/base.apk) at dev.eduardoroth.mediaplayer.MediaPlayer.create(MediaPlayer.java:82) at dev.eduardoroth.mediaplayer.MediaPlayerPlugin.lambda$create$1(MediaPlayerPlugin.java:178) at dev.eduardoroth.mediaplayer.MediaPlayerPlugin.$r8$lambda$G28Hg1VjyX6j7yiIZP0uf9avMwI(MediaPlayerPlugin.java) at dev.eduardoroth.mediaplayer.MediaPlayerPlugin$$ExternalSyntheticLambda9.run(D8$$SyntheticClass:0) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6202) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:911) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:801) 2025-02-17 19:22:43.793 19204-19204 Process app.iptvweb I Sending signal. PID: 19204 SIG: 9 2025-02-17 19:22:43.878 615-659 InputDispatcher system_server E channel 'c3eca51 app.iptvweb/app.iptvweb.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!

Here's the implementation code:

``

import { BackButtonListenerEvent, App as CapacitorApp } from "@capacitor/app";
import { Capacitor } from "@capacitor/core";
import { MediaPlayer } from "@eduardoroth/media-player";
import { useAuth } from "@providers/AuthProvider";
import { CategoryType } from "@types/index";
import { adMob } from "@utils/capacitorAdMob";
import { capVideoListener } from "capacitor-video-player";
import {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from "react";
import { useNavigate } from "react-router-dom";

interface NativePlayerProps {
  stream: string | null;
  poster?: string | null;
  title: string;
  smallTitle?: string;
  type: CategoryType;
  onFinished?: () => Promise<void>;
  onProgress?: (time: number) => Promise<void>;
  onPlayerExit?: () => void;
}

const NativePlayer = forwardRef(
  (
    {
      stream,
      poster,
      type,
      title,
      smallTitle,
      onFinished,
      onProgress,
      onPlayerExit,
    }: NativePlayerProps,
    ref
  ) => {
    const playerId = "video-player";
    const [isInitialized, setIsInitialized] = useState<boolean>(false);
    const { isUserPro } = useAuth();
    const isNative = Capacitor.isNativePlatform();
    const isFullScreen = useRef<boolean>(false);

    const disposePlayer = async () => {
      await MediaPlayer.removeAll();
      await MediaPlayer.removeAllListeners({ playerId });
      setIsInitialized(false);
    };

    const playVideo = async (seekTime?: number) => {
      if (!isInitialized) {
        await initializeNativePlayer(seekTime);
      }
      if (seekTime !== undefined) {
        await MediaPlayer.setCurrentTime({ playerId, time: seekTime });
      }
      const isReady = await MediaPlayer.isPlaying({ playerId });
      if (!isReady.value) {
        console.log("Starting playback...");
        if (seekTime !== undefined) {
          await MediaPlayer.setCurrentTime({ playerId, time: seekTime });
        }
        await MediaPlayer.play({ playerId });
      }
    };

    const initializeNativePlayer = async (seektime?: number) => {
      if (isInitialized) return;
      if (stream) {
        try {
          await MediaPlayer.create({
            url: stream,
            playerId,
            android: {
              enablePiP: true,
              enableBackgroundPlay: true,
              automaticallyEnterPiP: true,
            },
            extra: {
              title,
              subtitle: smallTitle || "",
              showControls: true,
              autoPlayWhenReady: false,
              poster: poster ?? undefined,
            },
          });

          attachErrorListener();
          // addKeyListeners();
          setIsInitialized(true);

          MediaPlayer.addListener(
            "MediaPlayer:Ready",
            async (_data: capVideoListener) => {
              console.log("MediaPlayer:Ready");
              setIsInitialized(true);
              if (seektime !== undefined) {
                await MediaPlayer.setCurrentTime({ playerId, time: seektime });
              }
              // await MediaPlayer.play({ playerId });
            }
          );

          MediaPlayer.addListener(
            "MediaPlayer:TimeUpdated",
            async (event: { playerId: string; currentTime: number }) => {
              if (event.currentTime && onProgress) {
                await onProgress(event.currentTime);
              }
            }
          );

          MediaPlayer.addListener(
            "MediaPlayer:Ended",
            async (_event: { playerId: string }) => {
              if (onFinished) await onFinished();
            }
          );

          MediaPlayer.addListener(
            "MediaPlayer:Removed",
            async (_event: { playerId: string }) => {
              if (!isUserPro) {
                adMob.interstitial();
              }
              CapacitorApp.removeAllListeners();
              disposePlayer();
              if (onPlayerExit) onPlayerExit();
            }
          );

          MediaPlayer.addListener(
            "MediaPlayer:FullScreen",
            async (event: { playerId: string; isInFullScreen: boolean }) => {
              if (event.isInFullScreen) {
                isFullScreen.current = true;
              } else {
                isFullScreen.current = false;
              }
            }
          );
        } catch (error) {
          console.error("Error initializing native player:", error);
        }
      }
    };

    const attachErrorListener = () => {
      if (!isNative) {
        const mediaPlayer = document.querySelector(
          "#video-player media-player"
        );
        if (mediaPlayer) {
          mediaPlayer.addEventListener("error", (event) => {
            console.error("Media Player Error:", event);
            setIsInitialized(false);
          });
        }
      }
    };


    const navigate = useNavigate();

    useEffect(() => {
      CapacitorApp.addListener(
        "backButton",
        async (_event: BackButtonListenerEvent) => {
          if (!isFullScreen.current) {
            navigate(-1);
          }
        }
      );
      return () => {
        CapacitorApp.removeAllListeners();
      };
    }, [stream, type]);

    useImperativeHandle(ref, () => ({
      playVideo,
    }));

    useEffect(() => {
      let isMounted = true; // Prevent multiple instances

      const init = async () => {
        await disposePlayer();
        if (isMounted) {
          await initializeNativePlayer();
        }
      };

      init();
      return () => {
        isMounted = false;
        disposePlayer();
      };
    }, [stream, type]);

    return (
      <>
        {!!poster && !isInitialized && (
          <>
            <div
              style={{
                position: "absolute",
                top: 0,
                left: 0,
                width: "100%",
                height: "100%",
                background: `
                    linear-gradient(to bottom, var(--main-bg-color) 0%, transparent 10%, transparent 90%, var(--main-bg-color) 100%),
                    linear-gradient(to right, var(--main-bg-color) 0%, transparent 10%, transparent 90%, var(--main-bg-color) 100%)
                  `,
                zIndex: 1,
              }}
            ></div>
            <img
              src={poster}
              style={{
                display: "block",
                position: "absolute",
                top: "50%",
                left: "50%",
                transform: "translate(-50%, -50%)",
                width: "100%",
                height: "99%",
                objectFit: type == CategoryType.LIVE ? "contain" : "cover",
                objectPosition: "center",
              }}
            />
          </>
        )}

        <div
          id="video-player"
          style={{
            width: "100%",
            maxHeight: "100%",
          }}
        ></div>
      </>
    );
  }
);

export default NativePlayer;

``

Why is this happening? Is it an issue with my implementation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant