虽然Android4.1之后版本通过MediaPlayer的setNextMediaPlayer
()方法视频无缝播放,但是国产的N多ARM芯片并不支持这一特性,
如何才能让现有的平台达到无缝播放效果,方法有N多种,比如通过http的ts流方式或者将多个文件合并成一个文件在去播放,就可以变相解决该问题。
经过测试可以把同种编码格式的mpg文件cat在一起播放以达到目的,笔者顺着这个思路逐步从Linux kernel层到Android JNI和App层
逐步来实现;
java播放层
1、设置要播放的文件总大小
2、设置播放序列
3、将虚拟的proc内存文件赋值给播放器
int fd = MpgFS.open("/dev/mpg_fs");
int fileSize = 8290340 + 16240676 + 16240676 + 16240676;
MpgFS.setFileSize(fd, fileSize);
List<PlayNode> list = new ArrayList<PlayNode>();
list.add(new PlayNode("/mnt/sdcard/576/FM0.mpg", 8290340, 0));
list.add(new PlayNode("/mnt/sdcard/576/FM1.mpg", 16240676, 1));
list.add(new PlayNode("/mnt/sdcard/576/FM2.mpg", 16240676, 2));
list.add(new PlayNode("/mnt/sdcard/576/FM3.mpg", 16240676, 3));
MpgFS.setPlayList(list, fd);
play.setVideoPath("/proc/mpg_fs");
JNI层的java部分
import java.util.List;
public class MpgFS {
static {
System.loadLibrary("mpgfs_jni");
}
public static final int NODE_SIZE = 128;
public native static int open(String device);
public native static int close(int fd);
private native static int ioctl(int fd, int cmd, byte[] buf, long len);
public static void int2buf(int value, byte[] buf, int offset) {
buf[offset + 0] = (byte) ((value >> 0) & 0xff);
buf[offset + 1] = (byte) ((value >> 8) & 0xff);
buf[offset + 2] = (byte) ((value >> 16) & 0xff);
buf[offset + 3] = (byte) ((value >> 24) & 0xff);
}
public static int setFileSize(int fd, long size) {
return ioctl(fd, 5, null, size);
}
public static int setPlayList(List<PlayNode> list, int fd) {
if (list == null || list.size() == 0) {
return -1;
}
int size = list.size();
byte[] buffer = new byte[NODE_SIZE * size];
for (int i = 0; i < size; i++) {
int offset = i * NODE_SIZE;
PlayNode node = list.get(i);
int2buf(node.size,