Search code examples
javaandroidvideoandroid-video-playeravi

Need get correct AVI Player class to play all AVI video files inside android application


I try to get correct AVI video player to play AVI file since my current AVI Player class looks like not work really good anymore.

Some AVI files can play correctly, but the others can not.

People who know which AVI Video player class play all avi files exactly,

Please help me,

Thank you,

p/s :

I don't want intent to 3rd application to play AVI file.

Below codes is current I used to play AVI files:

AVI Player.java package runnable;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

import iterface.IVideoSink;

public class VideoPlayer implements Runnable {
private final int FPS = 24;
/**
 * String section
 */
private boolean IS_ALIVE = true;
private long LAST_FRAME_TIME;
/**
 * Data section
 */
private ArrayList<IVideoSink> mAlVideoSinks;
/**
 * Others section
 */
private BufferedInputStream mBufferedInputStream;

public VideoPlayer(String filename) {
    mAlVideoSinks = new ArrayList<IVideoSink>();

    try {
        mBufferedInputStream = new BufferedInputStream(new FileInputStream(filename));
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

public void addVideoSink(IVideoSink videoSink) {
    synchronized (mAlVideoSinks) {
        mAlVideoSinks.add(videoSink);
    }
}

public void removeVideoSink(IVideoSink videoSink) {
    synchronized (mAlVideoSinks) {
        if (mAlVideoSinks.contains(videoSink))
            mAlVideoSinks.remove(videoSink);
    }
}

@Override
public void run() {
    int count = 0;

    while (IS_ALIVE) {
        if (LAST_FRAME_TIME == 0) {
            LAST_FRAME_TIME = System.currentTimeMillis();
        }

        try {
            long currentTime = System.currentTimeMillis();
            if (currentTime - LAST_FRAME_TIME < 1000 / FPS) {
                Thread.sleep(1000 / FPS - (currentTime - LAST_FRAME_TIME));
            }
            LAST_FRAME_TIME = System.currentTimeMillis();

            int b0 = mBufferedInputStream.read();
            if (b0 == -1) break;
            int b1 = mBufferedInputStream.read();
            int b2 = mBufferedInputStream.read();
            int b3 = mBufferedInputStream.read();

            count = b0 + (b1 << 8) + (b2 << 16) + (b3 << 24);
            byte[] buffer = new byte[count];
            int readCount = mBufferedInputStream.read(buffer, 0, count);
            for (IVideoSink videoSink : mAlVideoSinks) {
                videoSink.onFrame(buffer, null);
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    try {
        mBufferedInputStream.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    for (IVideoSink videoSink : mAlVideoSinks) {
        videoSink.onVideoEnd();
    }

}

public void stop() {
    IS_ALIVE = false;
}

}

PCM Player.java

package runnable;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;

import java.util.ArrayList;

public class PCMPlayer implements Runnable {
/**
 * String section
 */
private boolean IS_ALIVE = true;
/**
 * Data section
 */
private ArrayList<byte[]> mAlBuffers = new ArrayList<byte[]>();
/**
 * Other section
 */
private AudioTrack mAudioTrack;

public PCMPlayer() {
}

@Override
public void run() {
    int bufSize = AudioTrack.getMinBufferSize(8000,
            AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT);
    mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            8000,
            AudioFormat.CHANNEL_CONFIGURATION_MONO,
            AudioFormat.ENCODING_PCM_16BIT,
            bufSize,
            AudioTrack.MODE_STREAM);
    mAudioTrack.play();

    while (IS_ALIVE) {
        byte[] buffer = null;
        boolean dataFlag = true;

        while (dataFlag) {
            synchronized (mAlBuffers) {
                if (mAlBuffers.size() > 0) {
                    buffer = mAlBuffers.remove(0);
                } else {
                    dataFlag = false;
                    break;
                }
            }

            mAudioTrack.write(buffer, 0, buffer.length);
        }

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    mAudioTrack.stop();
    mAudioTrack.release();
}

public void writePCM(byte[] pcm) {
    synchronized (mAlBuffers) {
        byte[] buffer = new byte[pcm.length];
        System.arraycopy(pcm, 0, buffer, 0, buffer.length);
        mAlBuffers.add(buffer);
    }
}

public void stop() {
    IS_ALIVE = false;
}
}

Solution

  • I was pretty happy with Exoplayer, it was simple and it was quick, and I could use it on any page in my app, its recently deprecated and been taken over by android, is now called Media3.Exoplayer, Android have taken it over and the lines of code now go on and on, try it if you like.

    https://medium.com/@rawatsumit115/play-videos-by-using-jetpack-media3-exoplayer-in-android-kotlin-c736136de580