package com.ambi.multiplevlc;
import java.lang.ref.WeakReference;
import org.videolan.libvlc.EventHandler;
import org.videolan.libvlc.IVideoPlayer;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.LibVlcUtil;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaList;
import org.videolan.libvlc.NativeCrashHandler;
import org.videolan.libvlc.NativeCrashHandler.OnNativeCrashListener;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.Toast;
public class VideoView {
public static final String TAG = "MultipleVLC";
private String mFilePath;
private SurfaceView mSurface;
private SurfaceHolder holder;
private LibVLC libvlc;
private int mVideoWidth;
private int mVideoHeight;
private final static int VideoSizeChanged = -1;
private Activity mContext;
private EventHandler mEventHandler;
private FrameLayout mSurfaceFrame;
/*************
* IVideoPlayer
*************/
IVideoPlayer mVideoPlayer = new IVideoPlayer(){
@Override
public void eventHardwareAccelerationError() {
Log.e(TAG, "Error with hardware acceleration");
releasePlayer();
Toast.makeText(mContext, "Error with hardware acceleration", Toast.LENGTH_LONG).show();
}
@Override
public void setSurfaceLayout(int width, int height, int visible_width,
int visible_height, int sar_num, int sar_den) {
Message msg = Message.obtain(mHandler, VideoSizeChanged, width, height);
msg.sendToTarget();
}
// Used only for old stuff
@Override
public int configureSurface(Surface surface, int width, int height, int hal) {
Log.d("", "configureSurface: width = " + width + ", height = " + height);
if (LibVlcUtil.isICSOrLater() || surface == null)
return -1;
if (width * height == 0)
return 0;
if(hal != 0)
holder.setFormat(hal);
holder.setFixedSize(width, height);
return 1;
}
};
/*************
* Surface
*************/
SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
}
public void surfaceChanged(SurfaceHolder surfaceholder, int format,
int width, int height) {
if (libvlc != null)
libvlc.attachSurface(holder.getSurface(), mVideoPlayer);
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
}
};
/*************
* Events
*************/
private Handler mHandler = new MyHandler(this);
private static class MyHandler extends Handler {
private WeakReference<VideoView> mOwner;
public MyHandler(VideoView owner) {
mOwner = new WeakReference<VideoView>(owner);
}
@Override
public void handleMessage(Message msg) {
VideoView player = mOwner.get();
// SamplePlayer events
if (msg.what == VideoSizeChanged) {
player.setSize(msg.arg1, msg.arg2);
return;
}
// Libvlc events
Bundle b = msg.getData();
switch (b.getInt("event")) {
case EventHandler.MediaPlayerEndReached:
player.releasePlayer();
break;
case EventHandler.MediaPlayerPlaying:
case EventHandler.MediaPlayerPaused:
case EventHandler.MediaPlayerStopped:
default:
break;
}
}
}
public VideoView(SurfaceView view, String url, Activity ac, EventHandler handler, FrameLayout frame){
mSurfaceFrame = frame;
mContext = ac;
mFilePath = url;
mSurface = view;
holder = mSurface.getHolder();
holder.addCallback(mSHCallback);
mEventHandler = handler;
}
public OnNativeCrashListener nativecrashListener = new OnNativeCrashListener(){
@Override
public void onNativeCrash() {
Log.e("vlcdebug", "nativecrash");
}
};
public void createPlayer() {
releasePlayer();
try {
String media = mFilePath;
// Create a new media player
libvlc = new LibVLC();
libvlc.init(mContext);
libvlc.setHardwareAcceleration(LibVLC.HW_ACCELERATION_FULL);
libvlc.setSubtitlesEncoding("");
libvlc.setAout(LibVLC.AOUT_OPENSLES);
libvlc.setTimeStretching(true);
libvlc.setVerboseMode(true);
libvlc.setNetworkCaching(1000);
NativeCrashHandler.getInstance().setOnNativeCrashListener(nativecrashListener);
if(LibVlcUtil.isGingerbreadOrLater())
libvlc.setVout(LibVLC.VOUT_ANDROID_WINDOW);
else
libvlc.setVout(LibVLC.VOUT_ANDROID_SURFACE);
LibVLC.restartInstance(mContext);
mEventHandler.addHandler(mHandler);
holder.setKeepScreenOn(true);
MediaList list = libvlc.getMediaList();
list.clear();
list.add(new Media(libvlc, LibVLC.PathToURI(media)), false);
libvlc.playIndex(0);
mute();
} catch (Exception e) {
Log.e(TAG, e.toString());
Toast.makeText(mContext, "Error creating player!", Toast.LENGTH_LONG).show();
}
}
public void releasePlayer() {
if (libvlc == null)
return;
mEventHandler.removeHandler(mHandler);
libvlc.stop();
libvlc.detachSurface();
holder = null;
libvlc.closeAout();
libvlc.destroy();
libvlc = null;
mVideoWidth = 0;
mVideoHeight = 0;
}
private void setSize(int width, int height) {
if(libvlc!=null){
libvlc.closeAout();
libvlc.setVolume(0);
}
// Dimensions of the native video
mVideoWidth = width;
mVideoHeight = height;
if (mVideoWidth * mVideoHeight <= 1)
return;
// Dimensions of the device screen
int deviceW = mContext.getWindow().getDecorView().getWidth();
int deviceH = mContext.getWindow().getDecorView().getHeight();
// Dimensions of the surface frame
int surfaceFrameW = mSurfaceFrame.getMeasuredWidth();
int surfaceFrameH = mSurfaceFrame.getMeasuredHeight();
float videoAR = (float) mVideoWidth / (float) mVideoHeight;
float surfaceFrameAr = (float) surfaceFrameW / (float) surfaceFrameH;
int vidW = surfaceFrameW;
int vidH = surfaceFrameH;
if (surfaceFrameAr < videoAR)
vidH = (int) (surfaceFrameW / videoAR);
else
vidW = (int) (surfaceFrameH * videoAR);
// force surface buffer size
if(holder!=null){
holder.setFixedSize(mVideoWidth, mVideoHeight);
}
else{
Toast.makeText(mContext, "Holder was null!!!", Toast.LENGTH_SHORT);
}
// set display size
LayoutParams lp = mSurface.getLayoutParams();
lp.width = vidW;
lp.height = vidH;
mSurface.setLayoutParams(lp);
mSurface.invalidate();
}
public void mute(){
libvlc.closeAout();
libvlc.setVolume(0);
}
}