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 com.ambi.multiplevlc.R;
import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import android.widget.Toast;
public class VideoFragment extends Fragment implements SurfaceHolder.Callback, IVideoPlayer{
public static final String TAG = "VideoFragment";
public static final String VIDEO_URL = "VIDEO_URL";
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 Context mContext;
private EventHandler mEventHandler;
private ViewGroup mContainer;
public static VideoFragment newInstance(String videoURL) {
VideoFragment fragment = new VideoFragment();
Bundle args = new Bundle();
args.putString(VIDEO_URL, videoURL);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
View view = inflater.inflate(R.layout.fragment_video, container, false);
mContainer = container;
mContext = getActivity();
mFilePath = this.getArguments().getString(VIDEO_URL);
mSurface = (SurfaceView) view.findViewById(R.id.fragment_videoview_surface);
holder = mSurface.getHolder();
holder.addCallback(this);
return view;
}
public void createPlayer() {
releasePlayer();
try {
String media = mFilePath;
// Create a new media player
libvlc = new LibVLC();
mEventHandler = libvlc.getEventHandler();
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();
}
}
/*************
* Events
*************/
private Handler mHandler = new MyHandler(this);
private static class MyHandler extends Handler {
private WeakReference<VideoFragment> mOwner;
public MyHandler(VideoFragment owner) {
mOwner = new WeakReference<VideoFragment>(owner);
}
@Override
public void handleMessage(Message msg) {
VideoFragment 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 OnNativeCrashListener nativecrashListener = new OnNativeCrashListener() {
@Override
public void onNativeCrash() {
Log.e("vlcdebug", "nativecrash");
}
};
public void releasePlayer() {
if (libvlc == null)
return;
mEventHandler.removeHandler(mHandler);
libvlc.stop();
libvlc.detachSurface();
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 surface frame
int surfaceFrameW = mContainer.getMeasuredWidth();
int surfaceFrameH = mContainer.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).show();
}
// 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);
}
@Override
public void onResume(){
Log.d(TAG, "onResume");
super.onResume();
createPlayer();
}
@Override
public void onPause() {
Log.d(TAG, "onPause");
super.onPause();
releasePlayer();
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
super.onDestroy();
releasePlayer();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if (libvlc != null)
libvlc.attachSurface(holder.getSurface(), this);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
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;
}
}