Francesco Galgani
Francesco Galgani

Reputation: 6249

MediaPlayer generates "can't play this video" error on Android at the end of an HLS streaming

Note for the readers: this question refers only to Codename One, please don't post answers related to Android Studio.

This question has already an answer here: https://stackoverflow.com/a/51605375/1277576 but that answer it's not applicable to my code, because I cannot download a live streaming, I can only check that it exists or not before starting the MediaPlayer.

At the end of the streaming, detected by the MediaManager "completion handler" used in the following code, Android generates the annoying dialog "can't play this video". It doesn't happen all the times, but often enough. My question is how to avoid that popup message. I know that an hack exists to prevent the showing of that error, but it involves native code: https://stackoverflow.com/a/24380224/1277576

My code (already posted in the question CN.setScreenSaverEnabled(false); and MediaPlayer), note that videoUrl is an HLS live streaming:

    private void playVideo(Form parent, String videoUrl) {
        CN.setScreenSaverEnabled(false);
        Form player = new Form(new BorderLayout());
        player.getToolbar().setBackCommand("Back", Toolbar.BackCommandPolicy.ALWAYS, e -> {
            if (mp != null) {
                mp.getMedia().cleanup();
            }
            CN.setScreenSaverEnabled(true);
            parent.showBack();
        });
        player.add(BorderLayout.CENTER, FlowLayout.encloseCenterMiddle(
                new SpanLabel("Stream will start playing automatically when it is live")));

        player.addShowListener(l -> {
            while (!Util.downloadUrlToStorage(videoUrl, "temp.m3u8", false)) {
                CN.invokeAndBlock(() -> Util.sleep(1000));
            }
            try {
                // note that we cannot play the locally downloaded m3u8
                Media video = MediaManager.createMedia(videoUrl, true, () -> {
                    // completion handler, it's invoked when the stream connection is lost
                    if (mp != null) {
                        mp.getMedia().cleanup();
                    }
                    CN.setScreenSaverEnabled(true);
                    parent.showBack();
                });
                video.setNativePlayerMode(false);
                if (mp != null) {
                    mp.getMedia().cleanup();
                }
                mp = new MediaPlayer(video);
                mp.setAutoplay(true);
                mp.setHideNativeVideoControls(true);
                mp.setMaximize(false);
                player.removeAll();
                player.add(BorderLayout.CENTER, mp);
                player.revalidate();
            } catch (Exception err) {
                Log.e(err);
                ToastBar.showErrorMessage("Error loading straming");
            }
        });

        player.show();
    }

Upvotes: 2

Views: 124

Answers (1)

Shai Almog
Shai Almog

Reputation: 52760

We'll change our native implementation to return true for this event handler too so we'll grab that event as well. I can't think of a case where a user would want to see the native android dialog here for media playback.

Upvotes: 1

Related Questions