libgdx / gdx-video

A libGDX cross platform video rendering extension
Apache License 2.0
145 stars 50 forks source link

Android video playback audio works but no video #48

Closed MaximilianWang closed 3 years ago

MaximilianWang commented 7 years ago

Hello,

Revisiting this extension after some inactivity and am currently trying to get mp4 video working on android. I have created a Screen that should be playing video. The problem is that the screen remains blank but the audio plays in the background.

Can you provide any guidance? Ideally I want to be able to render video on android onto a specific texture (in an Actor) so that I can put it in a stage and have other Actors rendered on top of the video.

Below is an excerpt of my Screen class: `public VideoPlayer videoPlayer;

boolean videoLoaded = false;

@Override
public void show() {

    videoPlayer = VideoPlayerCreator.createVideoPlayer();
    videoPlayer.resize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
    videoPlayer.setOnVideoSizeListener(new VideoPlayer.VideoSizeListener() {
        @Override
        public void onVideoSize(float v, float v2) {
            videoLoaded = true;
        }
    });

    try {
        videoPlayer.play(Gdx.files.absolute("/path/to/file.mp4"));

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

    Gdx.gl.glEnable(GL20.GL_CULL_FACE);
    Gdx.gl.glCullFace(GL20.GL_BACK);

}

@Override
public void render(float delta) {

    Gdx.gl.glClearColor(0, 0, 0, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    if(videoLoaded) {
        if (!videoPlayer.render()) { // As soon as the video is finished, we start the file again using the same player.
            try {
                videoLoaded = false;
                videoPlayer.play(Gdx.files.absolute("/path/to/file.mp4"));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

}`
MaximilianWang commented 7 years ago

After further investigation it seems that this problem is device specific. On some devices it can even play two concurrent videos with no problems but on some it is just blank screen with audio in the back ground.

RBogie commented 7 years ago

In that case it can only be one of two issues: Either the device does not support the video codec used, or the device does not support the SurfaceTexture that is used for efficient video -> texture conversion

MaximilianWang commented 7 years ago

I see. So if I replace SurfaceTexture then that may do the trick?

Also I am currently trying to play videos consecutively by invoking videoPlayer.play(new file) when the current one is completed. The problem is that it causes the entire app to freeze for a little bit and then go back to normal as the next video comes in. How would you suggest I go about doing this in a way that does not freeze the UI thread? Would I be able to create another VideoPlayer object and load the next video (but not invoke mediaPlayer.start()) in a separate thread and then pass the new object to the Screen object?

RBogie commented 7 years ago

Replacing SurfaceTexture is hardly possible. However, codecs are the most likely issue anyway, so I would first look into this (Try to see whether the android media player can play the file. If it does, the device does not support SurfaceTexture. If it does not play the video, it is a codec issue).

Gdx-video does not prevent you in making multiple players. However, the android mediaplayer that is used in the background does have some requirements on threading. I would check the android documentation to see what it states exactly about the threading (It's a long time since I implemented the code, so I can't remember the threading details on android anymore).

dbeef commented 7 years ago

or the device does not support the SurfaceTexture that is used for efficient video -> texture conversion

Pardon, but how exactly may I handle this particular situation?

RBogie commented 7 years ago

If that is the case, there is no easy/clear fix. The problem is that the only alternative would be using the desktop approach with ffmpeg. However, on a mobile phone the performance would instantly become an issue.

Have you tried whether the file works in different players?

dbeef commented 7 years ago

Thx for a quick answer!

Any Android update would not fix it? I'm 4.2.2.

If no, would you recommend interfacing native android MediaPlayer as necessity?

RBogie commented 7 years ago

Android updates might fix it, given the fact that the video also doesn't work in a different player (try to play it in your device's gallery.

I would say interfacing with the native android MediaPlayer is a necessity, because, unless the video is very small and low quality, the phone's cpu would struggle with decoding, and the bandwidth for texture transfers would be troublesome too. By using the native MediaPlayer, you can use the GPU for decoding, and don't have the extra step of getting the raw image to the GPU.

dbeef commented 7 years ago

I played it in a built-in android gallery, no errors, no crashes. When playing via gdx-video, there's only audio and a black screen. Tried also on an emulator of Nexus 5, same.

Pity, I'll try with the MediaPlayer, but thanks anyway, really good work with the project.

RBogie commented 7 years ago

The emulator is known to not work with gdx-video on certain SDK versions.

However, the fact that the video is playing in the gallery just fine, makes me believe that it is indeed the SurfaceTexture that is not supported. It might be fixed by an android update, however I think it is unlikely.

Honestly, I don't know how to fix this. You might try a different codec for the video, but then again, if it is the SurfaceTexture, it probably won't make a difference.

RBogie commented 7 years ago

Actually, I just see the example enabling culling. Could you try to see whether that might be hiding your texture?

dbeef commented 7 years ago

https://developer.android.com/guide/topics/graphics/opengl.html

Do you mean this one?

// enable face culling feature gl.glEnable(GL10.GL_CULL_FACE);

RBogie commented 7 years ago

Yes. You could either disable culling, or try Gdx.gl.glCullFace(GL20.GL_FRONT_AND_BACK)

dbeef commented 7 years ago

Tried both, separatly, and after that, combined one after another, didn't work. Also, my log is writing this every render call:

06-18 12:01:09.142 16524-16579/ E/emuglGLESv2_enc: glDrawElements: no data bound to the command - ignoring 06-18 12:01:09.208 16524-16579/ W/GLConsumer: [SurfaceTexture-100-16524-1] bindTextureImage: clearing GL error: 0x502

RBogie commented 7 years ago

Hmmz, don't know what's wrong because the glDrawElements should have data bound.

I will look into this further when I have some time (won't be before at least thursday)

dbeef commented 7 years ago

For more details, video works perfectly on desktop project, on android one I tried .3gp, .webm and .mp4, every one of them plays audio but no video.

Thanks for help

zumbarlal commented 5 years ago

For android video play using libgdx You need to use below in screen class

@Override
    public void render(float delta) {
         batch.begin();
         if (videoPlayerAndroid!=null && videoPlayerAndroid.isBuffered()) {
               videoPlayerAndroid.render();
        }
}

and you can play video from activity

Gdx.app.postRunnable(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                VideoPlayerAndroid videoPlayerAndroid = new VideoPlayerAndroid(sensesMainBoard.getmDrawScreen().getStage().getViewport());
//                        videoPlayerAndroid.resize(200,100);
                                FileHandle fileHandle = new FileHandle(getPath(videoUri));
                                videoPlayerAndroid.play(fileHandle);
                                screen.addVideo(videoPlayerAndroid);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        }
                    });
SimonIT commented 3 years ago

Could you try if the issue persists with the newest snapshot?