Android MediaPlayer does not display video, only play audio - android

I have a video file in location /sdcard/abc/a.3gp. Now when I try to play the file in android emulator using the media player that I have just created, I get only the audio, the video is not displayed. The screen remains blank (when it is supposed to play the video).
Here is the media player code that I am using:
package com.example.helloandroid;
import com.example.helloandroid.R;
import android.app.Activity;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import android.widget.VideoView;
public class HelloAndroidActivity extends Activity implements
OnBufferingUpdateListener, OnCompletionListener,
OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback {
private static final String TAG = "MediaPlayerDemo";
private int mVideoWidth;
private int mVideoHeight;
private MediaPlayer mMediaPlayer;
private SurfaceView mPreview;
private SurfaceHolder holder;
private String path;
private Bundle extras;
private static final String MEDIA = "media";
private static final int LOCAL_AUDIO = 1;
private static final int STREAM_AUDIO = 2;
private static final int RESOURCES_AUDIO = 3;
private static final int LOCAL_VIDEO = 4;
private static final int STREAM_VIDEO = 5;
private boolean mIsVideoSizeKnown = false;
private boolean mIsVideoReadyToBePlayed = false;
/**
*
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
mPreview = (SurfaceView) findViewById(R.id.surface_view);
holder = mPreview.getHolder();
holder.addCallback(this);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
extras = getIntent().getExtras();
}
private void playVideo() {
doCleanUp();
try {
path = "/sdcard/abc/a.3gp";
if (path == "") {
// Tell the user to provide a media file URL.
Toast
.makeText(
HelloAndroidActivity.this,
"Please edit MediaPlayerDemo_Video Activity, "
+ "and set the path variable to your media file path."
+ " Your media file must be stored on sdcard.",
Toast.LENGTH_LONG).show();
}
// Create a new media player and set the listeners
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(path);
mMediaPlayer.setDisplay(holder);
mMediaPlayer.prepare();
mMediaPlayer.setOnBufferingUpdateListener(this);
mMediaPlayer.setOnCompletionListener(this);
mMediaPlayer.setOnPreparedListener(this);
mMediaPlayer.setOnVideoSizeChangedListener(this);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
catch (Exception e) {
Log.e(TAG, "error: " + e.getMessage(), e);
}
}
public void onBufferingUpdate(MediaPlayer arg0, int percent) {
Log.d(TAG, "onBufferingUpdate percent:" + percent);
}
public void onCompletion(MediaPlayer arg0) {
Log.d(TAG, "onCompletion called");
}
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
Log.v(TAG, "onVideoSizeChanged called");
if (width == 0 || height == 0) {
Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")");
return;
}
mIsVideoSizeKnown = true;
mVideoWidth = width;
mVideoHeight = height;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void onPrepared(MediaPlayer mediaplayer) {
Log.d(TAG, "onPrepared called");
mIsVideoReadyToBePlayed = true;
if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
startVideoPlayback();
}
}
public void surfaceChanged(SurfaceHolder surfaceholder, int i, int j, int k) {
Log.d(TAG, "surfaceChanged called");
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
Log.d(TAG, "surfaceDestroyed called");
}
public void surfaceCreated(SurfaceHolder holder) {
Log.d(TAG, "surfaceCreated called");
playVideo();
}
#Override
protected void onPause() {
super.onPause();
releaseMediaPlayer();
doCleanUp();
}
#Override
protected void onDestroy() {
super.onDestroy();
releaseMediaPlayer();
doCleanUp();
}
private void releaseMediaPlayer() {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
private void doCleanUp() {
mVideoWidth = 0;
mVideoHeight = 0;
mIsVideoReadyToBePlayed = false;
mIsVideoSizeKnown = false;
}
private void startVideoPlayback() {
Log.v(TAG, "startVideoPlayback");
holder.setFixedSize(mVideoWidth, mVideoHeight);
mMediaPlayer.start();
}
}
....................................................................
Layout->main.xml file is:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/home_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<VideoView
android:id="#+id/surface_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</FrameLayout>
............................................................................
I am not sure if the error is in the xml file or in the code.
Moreover in the logs there is no trace of the error.
Please help me out.
Thanks.

Unfortunately, it seems like the one of wide-known Android emulator's disadvantages. It has very limited support of media playing, so video in most cases can't perform well. Even Google engineers advices to use real device and not an emulator to test MediaPlayer-related issues.

use SurfaceView in .xml file instead of VideoView
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/home_container"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<SurfaceView
android:id="#+id/surface_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</FrameLayout>
Let us know once you resolved problem.

Why don't you just use videoview, it's a wrapper of mediaplayer, easy to settup.
P/s: i saw in your code mMediaPlayer.setDisplay(holder); it's nonsense, you should use mMediaPlayer.setDisplay(surfaceHolder); inside surfaceCreated or pass surfaceHolder as a param in playvideo()

Related

How to add the android view on top of html view but not full screen?

I am creating the app in ionic framework and I am calling the custom plugin which have the video player. Now my problem is Video player is opening in new window rather than current opening window. I want it to open on top of my Html page but not full screen only half screen. the final page will have html page on top of that In right side half page i want my plugin to open.any help how to do this thanks in advance.
this is my plugin
package cordova.plugin.VLCPlugin;
import android.app.Activity;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import com.mindtree.gladiuscms.R;
import org.videolan.libvlc.EventHandler;
import org.videolan.libvlc.IVideoPlayer;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaList;
import java.lang.ref.WeakReference;
import cordova.plugin.VLCPlugin.util.SystemUiHider;
import cordova.plugin.VLCPlugin.util.UrlProvider;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*
* #see SystemUiHider
*/
public class FullscreenVlcPlayer extends Activity implements SurfaceHolder.Callback, IVideoPlayer {
private String urlToStream;
// Display Surface
private LinearLayout vlcContainer;
private SurfaceView mSurface;
private SurfaceHolder holder;
// Overlay / Controls
private FrameLayout vlcOverlay;
private ImageView vlcButtonPlayPause;
private Handler handlerOverlay;
private Runnable runnableOverlay;
private Handler handlerSeekbar;
private Runnable runnableSeekbar;
private SeekBar vlcSeekbar;
private TextView vlcDuration;
private TextView overlayTitle;
// media player
private LibVLC libvlc;
private int mVideoWidth;
private int mVideoHeight;
private final static int VideoSizeChanged = -1;
private UrlProvider urlProvider = new UrlProvider();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retrieve our url
// Bundle b = getIntent().getExtras();
UrlProvider urlProvider = UrlProvider.getInstance();
urlToStream = urlProvider.getUrl();
Log.d("Data url sdfjksdf", urlToStream);
// urlToStream = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";// b.getString("url", null);
// HIDE THE ACTION BAR
// getActionBar().hide();
// SETUP THE UI
try{
getActionBar().hide();
setContentView(R.layout.activity_fullscreen_vlc_player);
}catch(Exception e){
Log.d("TAG", "error");
}
// VLC
vlcContainer = (LinearLayout) findViewById(R.id.vlc_container);
mSurface = (SurfaceView) findViewById(R.id.vlc_surface);
// OVERLAY / CONTROLS
vlcOverlay = (FrameLayout) findViewById(R.id.vlc_overlay);
vlcButtonPlayPause = (ImageView) findViewById(R.id.vlc_button_play_pause);
vlcSeekbar = (SeekBar) findViewById(R.id.vlc_seekbar);
vlcDuration = (TextView) findViewById(R.id.vlc_duration);
overlayTitle = (TextView) findViewById(R.id.vlc_overlay_title);
// overlayTitle.setText("rtsp://172.22.68.96:21212/Stream-2");
// AUTOSTART
playMovie();
}
private void showOverlay() {
vlcOverlay.setVisibility(View.VISIBLE);
}
private void hideOverlay() {
vlcOverlay.setVisibility(View.GONE);
}
private void setupControls() {
getActionBar().hide();
// PLAY PAUSE
vlcButtonPlayPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (libvlc.isPlaying()) {
libvlc.pause();
// vlcButtonPlayPause.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_play_over_video));
} else {
libvlc.play();
// vlcButtonPlayPause.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_pause_over_video));
}
}
});
// SEEKBAR
handlerSeekbar = new Handler();
runnableSeekbar = new Runnable() {
#Override
public void run() {
if (libvlc != null) {
long curTime = libvlc.getTime();
long totalTime = (long) (curTime / libvlc.getPosition());
int minutes = (int) (curTime / (60 * 1000));
int seconds = (int) ((curTime / 1000) % 60);
int endMinutes = (int) (totalTime / (60 * 1000));
int endSeconds = (int) ((totalTime / 1000) % 60);
String duration = String.format("%02d:%02d / %02d:%02d", minutes, seconds, endMinutes, endSeconds);
vlcSeekbar.setProgress((int) (libvlc.getPosition() * 100));
vlcDuration.setText(duration);
}
handlerSeekbar.postDelayed(runnableSeekbar, 1000);
}
};
runnableSeekbar.run();
vlcSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
Log.v("NEW POS", "pos is : " + i);
//if (i != 0)
// libvlc.setPosition(((float) i / 100.0f));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
// OVERLAY
handlerOverlay = new Handler();
runnableOverlay = new Runnable() {
#Override
public void run() {
vlcOverlay.setVisibility(View.GONE);
toggleFullscreen(true);
}
};
final long timeToDisappear = 3000;
handlerOverlay.postDelayed(runnableOverlay, timeToDisappear);
vlcContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
vlcOverlay.setVisibility(View.VISIBLE);
handlerOverlay.removeCallbacks(runnableOverlay);
handlerOverlay.postDelayed(runnableOverlay, timeToDisappear);
}
});
}
public void playMovie() {
if (libvlc != null && libvlc.isPlaying())
return ;
vlcContainer.setVisibility(View.VISIBLE);
holder = mSurface.getHolder();
holder.addCallback(this);
createPlayer(urlToStream);
}
private void toggleFullscreen(boolean fullscreen)
{
WindowManager.LayoutParams attrs = getWindow().getAttributes();
if (fullscreen)
{
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
vlcContainer.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
else
{
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
}
getWindow().setAttributes(attrs);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setSize(mVideoWidth, mVideoHeight);
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
//releasePlayer();
}
#Override
protected void onDestroy() {
super.onDestroy();
releasePlayer();
}
/**
* **********
* Surface
* ***********
*/
public void surfaceCreated(SurfaceHolder holder) {
}
public void surfaceChanged(SurfaceHolder surfaceholder, int format,
int width, int height) {
if (libvlc != null)
libvlc.attachSurface(surfaceholder.getSurface(), this);
}
public void surfaceDestroyed(SurfaceHolder surfaceholder) {
}
private void setSize(int width, int height) {
mVideoWidth = width;
mVideoHeight = height;
if (mVideoWidth * mVideoHeight <= 1)
return;
// get screen size
int w = getWindow().getDecorView().getWidth();
int h = getWindow().getDecorView().getHeight();
// getWindow().getDecorView() doesn't always take orientation into
// account, we have to correct the values
boolean isPortrait = getResources().getConfiguration().orientation `**enter code here**`== Configuration.ORIENTATION_PORTRAIT;
if (w > h && isPortrait || w < h && !isPortrait) {
int i = w;
w = h;
h = i;
}
float videoAR = (float) mVideoWidth / (float) mVideoHeight;
float screenAR = (float) w / (float) h;
if (screenAR < videoAR)
h = (int) (w / videoAR);
else
w = (int) (h * videoAR);
// force surface buffer size
if (holder != null)
holder.setFixedSize(mVideoWidth, mVideoHeight);
// set display size
ViewGroup.LayoutParams lp = mSurface.getLayoutParams();
lp.width = w;
lp.height = h;
mSurface.setLayoutParams(lp);
mSurface.invalidate();
}
#Override
public void setSurfaceSize(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();
}
/**
* **********
* Player
* ***********
*/
private void createPlayer(String media) {
releasePlayer();
setupControls();
try {
if (media.length() > 0) {
Toast toast = Toast.makeText(this, media, Toast.LENGTH_LONG);
toast.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,
0);
toast.show();
}
// Create a new media player
libvlc = LibVLC.getInstance();
libvlc.setHardwareAcceleration(LibVLC.HW_ACCELERATION_FULL);
libvlc.eventVideoPlayerActivityCreated(true);
libvlc.setSubtitlesEncoding("");
libvlc.setAout(LibVLC.AOUT_OPENSLES);
libvlc.setTimeStretching(true);
libvlc.setChroma("RV32");
libvlc.setVerboseMode(true);
LibVLC.restart(this);
EventHandler.getInstance().addHandler(mHandler);
holder.setFormat(PixelFormat.RGBX_8888);
holder.setKeepScreenOn(true);
MediaList list = libvlc.getMediaList();
list.clear();
list.add(new Media(libvlc, LibVLC.PathToURI(media)), false);
libvlc.playIndex(0);
} catch (Exception e) {
Toast.makeText(this, "Could not create Vlc Player", Toast.LENGTH_LONG).show();
}
}
private void releasePlayer() {
if (handlerSeekbar != null && runnableSeekbar != null)
handlerSeekbar.removeCallbacks(runnableSeekbar);
EventHandler.getInstance().removeHandler(mHandler);
if (libvlc == null)
return;
libvlc.stop();
libvlc.detachSurface();
holder = null;
libvlc.closeAout();
mVideoWidth = 0;
mVideoHeight = 0;
}
/**
* **********
* Events
* ***********
*/
private Handler mHandler = new MyHandler(this);
private static class MyHandler extends Handler {
private WeakReference<FullscreenVlcPlayer> mOwner;
public MyHandler(FullscreenVlcPlayer owner) {
mOwner = new WeakReference<FullscreenVlcPlayer>(owner);
}
#Override
public void handleMessage(Message msg) {
FullscreenVlcPlayer player = mOwner.get();
// Player 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;
}
}
}
}
//it use some helper class and
xml file attached to this
cordova plugin
package cordova.plugin.VLCPlugin;
import android.app.Application;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Rect;
import android.widget.FrameLayout;
import com.mindtree.gladiuscms.R;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import org.json.JSONException;
import cordova.plugin.VLCPlugin.util.UrlProvider;
public class VLCPlugin extends CordovaPlugin {
UrlProvider urlProvider = new UrlProvider();
#Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
FrameLayout layout = (FrameLayout) webView.getView().getParent();
}
#Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
if(action.equals("play")) {
String url = args.getString(0);
UrlProvider urlProvide = UrlProvider.getInstance();
urlProvide.setUrl(url);
resources.getIdentifier("R.layout.activity_fullscreen_vlc_player", "layout", package_name);
cordova.getActivity().runOnUiThread(new Runnable() {
public void run() {
Application app = cordova.getActivity().getApplication();
Intent intent = new Intent(app, FullscreenVlcPlayer.class);
cordova.getActivity().startActivity(intent);
}
return false;
}
}
now i am cslling this plugin from my controller
window.vlcPlugin.onMediaLoad("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");}
an my html code is
<div ng-drag="true" ng-drag-data="video" ng-drag-success="onDragComplete()"></div>
i want to see video in this div
<div class="video_player_screen" ng-drop="tru >

My onDraw() method is never called

My issue is that no matter what I do, no matter how many questions and answers I read through on the internet, I cant get a simple rectangle to draw on my android device screen. Let me rephrase that, it shows up on screen but it wont change. I cant get an animation to update. onDraw() never calls multiple times, just once on startup. why? Here is my view objects code:
package prospect_industries.es;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class TestView extends View {
//Variables
public static final int SIZE = 300;
public float TOP = 0.0f;
public float LEFT = 0.0f;
public float RIGHT = 100f;
public float BOTTOM = 100f;
private Paint rectanglePaint;
private RectF rect1;
//Constructors
public TestView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
init();
}
public TestView(final Context context, final AttributeSet attrs) {
super(context, attrs, 0);
init();
}
public TestView(final Context context) {
super(context, null, 0);
init();
}
//View methods
#Override
protected void onDraw(final Canvas canvas){
canvas.drawRect(rect1, rectanglePaint);
Log.i("test1", "in onDraw");
}
#Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
final int chosenWidth = chooseDimension(widthMode, widthSize);
final int chosenHeight = chooseDimension(heightMode, heightSize);
setMeasuredDimension(chosenWidth, chosenHeight);
Log.i("test1", String.valueOf(chosenWidth));
Log.i("test1",String.valueOf(chosenHeight));
}
//Class Methods
private int chooseDimension(final int mode, final int size) {
switch (mode) {
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
return size;
case MeasureSpec.UNSPECIFIED:
default:
return getDefaultDimension();
}
}
private int getDefaultDimension() { return SIZE; }
private void init(){
requestFocus();
rectanglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
rectanglePaint.setColor(-1);
rectanglePaint.setStyle(Paint.Style.FILL);
rect1 = new RectF(LEFT, TOP, RIGHT, BOTTOM);
}
public void update() {
RIGHT += 10;
BOTTOM += 10;
rect1 = new RectF(LEFT, TOP, RIGHT, BOTTOM);
invalidate();
Log.i("test1", "in update");
}
}
Here is my main class which has a few methods for other things Im working on as well as a timer which calls the update() method inside of my test view object.
package prospect_industries.es;
import android.app.Activity;
import android.content.Context;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends Activity {
private boolean setup = false;
public int waitDelay = 1000; //Milliseconds - currently 1 second
private Timer checkTime;
private TimerTask listen;
private MediaRecorder mRecorder;
//Splashscreen
private Timer splashScreen;
private int waitTime = 3000; //3 seconds
private GaugeView mGaugeView;
private final Random RAND = new Random();
private TestView testview;
private SurfaceHolder surfaceHolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
//mGaugeView = (GaugeView) findViewById(R.id.gauge_view);
testview = (TestView) findViewById(R.id.test_view);
}
#Override
public void onStart() {
super.onStart();
//Timers
//1 second wait tick
checkTime = new Timer();
checkTime.schedule(new TimerTask() {
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
//mGaugeView.setTargetValue(RAND.nextInt(101));
testview.update();
}
});
}
}, 0, waitDelay);
//Set splash screen wait timer
splashScreen = new Timer();
splashScreen.schedule(new TimerTask() {
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
setContentView(R.layout.content_main);
}
});
splashScreen.cancel();
}
}, waitTime);
//set welcome screen
setContentView(R.layout.activity_welcome);
}
#Override
public void onStop() {
super.onStop();
if(checkTime != null) {
checkTime.cancel();
stop();
}
}
public void stop() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
public double getAmplitude() {
if (mRecorder != null)
return mRecorder.getMaxAmplitude();
else
return 0;
}
public void checkSound(){
if (mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setOutputFile("/dev/null");
try {
mRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mRecorder.start();
}
}
private static class MainView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder surfaceHolder;
public MainView(Context context) {
super(context);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
}
Lastly, here is the xml layout file which loads in the test view object.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#103681"
tools:context="prospect_industries.es.MainActivity">
<prospect_industries.es.TestView
android:layout_width="200dp"
android:layout_height="200dp"
android:id="#+id/test_view"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
I have been looking all over stackExchange for hours but I cant fix my problem, onDraw is only called once and never again no matter what I do. Right now the rectangle should be expanding out but it isnt being redrawn.
The problem is that you initialize the rectangle to be 1px wide and 1px tall and never resize it. You should be able to see 1 white pixel somewhere in the top left corner of your TestView.
Try changing the rect1 size to 0,0,100,100 and see if the problem persists.
public static final float TOP = 0.0f;
public static final float LEFT = 0.0f;
public static final float RIGHT = 100.0f;
public static final float BOTTOM = 100.0f;

How to select audio channels and subtitles in a video stream, using vlc lib for Android?

I am working in a stream video player in Android and need to show the subtitles of this stream (when they exist) and also show a way for the user to select one of the audio channels presents in the stream.
I am switching from Android MediaPlayer to VlcLib to be able to do it.
But I can't find any examples about how to do it.
Has anybody already done this? Can you share some example or show a clue?
Thanks very much for any help.
My code, wich is based on an example found in internet, is:
package com.wass08.vlcsimpleplayer;
import com.wass08.vlcsimpleplayer.util.SystemUiHider;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import org.videolan.libvlc.EventHandler;
import org.videolan.libvlc.IVideoPlayer;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
import org.videolan.libvlc.MediaList;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Map;
/**
* An example full-screen activity that shows and hides the system UI (i.e.
* status bar and navigation/system bar) with user interaction.
*
* #see SystemUiHider
*/
public class FullscreenVlcPlayer extends Activity implements SurfaceHolder.Callback, IVideoPlayer
{
private String urlToStream;
// Display Surface
private LinearLayout vlcContainer;
private SurfaceView mSurface;
private SurfaceView mSubtitlesSurface;
private SurfaceHolder holder;
private SurfaceHolder mSubtitlesSurfaceHolder;
// Overlay / Controls
private FrameLayout vlcOverlay;
private ImageView vlcButtonPlayPause;
private Handler handlerOverlay;
private Runnable runnableOverlay;
private Handler handlerSeekbar;
private Runnable runnableSeekbar;
private SeekBar vlcSeekbar;
private TextView vlcDuration;
private TextView overlayTitle;
// media player
private LibVLC libvlc;
private int mVideoWidth;
private int mVideoHeight;
private final static int VideoSizeChanged = -1;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Retrieve our url
Bundle b = getIntent().getExtras();
urlToStream = b.getString("url", null);
// HIDE THE ACTION BAR
getActionBar().hide();
// SETUP THE UI
setContentView(R.layout.activity_fullscreen_vlc_player);
// VLC
vlcContainer = (LinearLayout) findViewById(R.id.vlc_container);
mSurface = (SurfaceView) findViewById(R.id.vlc_surface);
mSubtitlesSurface = (SurfaceView) findViewById(R.id.subtitles_surface);
// OVERLAY / CONTROLS
vlcOverlay = (FrameLayout) findViewById(R.id.vlc_overlay);
vlcButtonPlayPause = (ImageView) findViewById(R.id.vlc_button_play_pause);
vlcSeekbar = (SeekBar) findViewById(R.id.vlc_seekbar);
vlcDuration = (TextView) findViewById(R.id.vlc_duration);
overlayTitle = (TextView) findViewById(R.id.vlc_overlay_title);
overlayTitle.setText(urlToStream);
// AUTOSTART
playMovie();
}
private void setSubtitles()
{
/* Only show the subtitles surface when using "Full Acceleration" mode */
//if (libvlc.getHardwareAcceleration() == 2)
//{
mSubtitlesSurface.setVisibility(View.VISIBLE);
//}
Map<Integer, String> mSubtitleTracksList;
Map<Integer, String> mAudioTracksList;
int numSubtitleTracks = libvlc.getSpuTracksCount();
int numAudioTracks = libvlc.getAudioTracksCount();
mSubtitleTracksList = libvlc.getSpuTrackDescription();
mAudioTracksList = libvlc.getAudioTrackDescription();
if (mSubtitleTracksList != null && mSubtitleTracksList.size() > 0)
{
}
if (mAudioTracksList != null && mAudioTracksList.size() > 0)
{
}
Log.d("LIBVLC_PLAYER", "Number of Subtitles Tracks = " + numSubtitleTracks);
Log.d("LIBVLC_PLAYER", "Number of Audio Tracks = " + numAudioTracks);
int i = 0;
for (Map.Entry<Integer, String> entry : mSubtitleTracksList.entrySet())
{
Log.d("LIBVLC_PLAYER", "Subtitle Track " + i + " = " + entry.getValue().toString());
i++;
}
libvlc.setSpuTrack(0);
i = 0;
for (Map.Entry<Integer, String> entry2 : mAudioTracksList.entrySet())
{
Log.d("LIBVLC_PLAYER", "Audio Track " + i + " = " + entry2.getValue().toString());
i++;
}
libvlc.setAudioTrack(0);
}
private final SurfaceHolder.Callback mSubtitlesSurfaceCallback = new SurfaceHolder.Callback()
{
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
if (libvlc != null)
{
libvlc.attachSubtitlesSurface(holder.getSurface());
Log.d("LIBVLC_PLAYER", "SurfaceHolder.Callback: width: " + width + " height: " + height);
}
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
Log.d("LIBVLC_PLAYER", "SurfaceHolder.Callback -> surfaceCreated");
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
libvlc.detachSubtitlesSurface();
Log.d("LIBVLC_PLAYER", "SurfaceHolder.Callback -> surfaceDestroyed");
}
};
private void showOverlay()
{
vlcOverlay.setVisibility(View.VISIBLE);
}
private void hideOverlay()
{
vlcOverlay.setVisibility(View.GONE);
}
private void setupControls()
{
getActionBar().hide();
// PLAY PAUSE
vlcButtonPlayPause.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View view)
{
if (libvlc.isPlaying())
{
libvlc.pause();
vlcButtonPlayPause.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_play_over_video));
}
else
{
libvlc.play();
vlcButtonPlayPause.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_pause_over_video));
}
}
}
);
// SEEKBAR
handlerSeekbar = new Handler();
runnableSeekbar = new Runnable()
{
#Override
public void run()
{
if (libvlc != null)
{
long curTime = libvlc.getTime();
long totalTime = (long) (curTime / libvlc.getPosition());
int minutes = (int) (curTime / (60 * 1000));
int seconds = (int) ((curTime / 1000) % 60);
int endMinutes = (int) (totalTime / (60 * 1000));
int endSeconds = (int) ((totalTime / 1000) % 60);
String duration = String.format("%02d:%02d / %02d:%02d", minutes, seconds, endMinutes, endSeconds);
vlcSeekbar.setProgress((int) (libvlc.getPosition() * 100));
vlcDuration.setText(duration);
}
handlerSeekbar.postDelayed(runnableSeekbar, 1000);
}
};
runnableSeekbar.run();
vlcSeekbar.setOnSeekBarChangeListener(
new SeekBar.OnSeekBarChangeListener()
{
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b)
{
Log.v("NEW POS", "pos is : " + i);
//if (i != 0)
// libvlc.setPosition(((float) i / 100.0f));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
}
);
// OVERLAY
handlerOverlay = new Handler();
runnableOverlay = new Runnable()
{
#Override
public void run()
{
vlcOverlay.setVisibility(View.GONE);
toggleFullscreen(true);
}
};
final long timeToDisappear = 3000;
handlerOverlay.postDelayed(runnableOverlay, timeToDisappear);
vlcContainer.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View view)
{
vlcOverlay.setVisibility(View.VISIBLE);
handlerOverlay.removeCallbacks(runnableOverlay);
handlerOverlay.postDelayed(runnableOverlay, timeToDisappear);
}
}
);
}
public void playMovie()
{
if (libvlc != null && libvlc.isPlaying())
{
return;
}
vlcContainer.setVisibility(View.VISIBLE);
holder = mSurface.getHolder();
holder.addCallback(this);
createPlayer(urlToStream);
}
private void toggleFullscreen(boolean fullscreen)
{
WindowManager.LayoutParams attrs = getWindow().getAttributes();
if (fullscreen)
{
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
vlcContainer.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
else
{
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
}
getWindow().setAttributes(attrs);
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
setSize(mVideoWidth, mVideoHeight);
}
#Override
protected void onResume()
{
super.onResume();
}
#Override
protected void onPause()
{
super.onPause();
//releasePlayer();
}
#Override
protected void onDestroy()
{
super.onDestroy();
releasePlayer();
}
/**
* **********
* Surface
* ***********
*/
public void surfaceCreated(SurfaceHolder holder)
{
}
public void surfaceChanged(SurfaceHolder surfaceholder, int format,
int width, int height)
{
if (libvlc != null)
{
libvlc.attachSurface(surfaceholder.getSurface(), this);
}
}
public void surfaceDestroyed(SurfaceHolder surfaceholder)
{
}
private void setSize(int width, int height)
{
mVideoWidth = width;
mVideoHeight = height;
if (mVideoWidth * mVideoHeight <= 1)
{
return;
}
// get screen size
int w = getWindow().getDecorView().getWidth();
int h = getWindow().getDecorView().getHeight();
// getWindow().getDecorView() doesn't always take orientation into
// account, we have to correct the values
boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
if (w > h && isPortrait || w < h && !isPortrait)
{
int i = w;
w = h;
h = i;
}
float videoAR = (float) mVideoWidth / (float) mVideoHeight;
float screenAR = (float) w / (float) h;
if (screenAR < videoAR)
{
h = (int) (w / videoAR);
}
else
{
w = (int) (h * videoAR);
}
// force surface buffer size
if (holder != null)
{
holder.setFixedSize(mVideoWidth, mVideoHeight);
}
// set display size
ViewGroup.LayoutParams lp = mSurface.getLayoutParams();
lp.width = w;
lp.height = h;
mSurface.setLayoutParams(lp);
mSurface.invalidate();
}
#Override
public void setSurfaceSize(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();
}
/**
* **********
* Player
* ***********
*/
private void createPlayer(String media)
{
releasePlayer();
setupControls();
try
{
if (media.length() > 0)
{
Toast toast = Toast.makeText(this, media, Toast.LENGTH_LONG);
toast.setGravity(
Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,
0
);
toast.show();
}
// Create a new media player
libvlc = LibVLC.getInstance();
libvlc.setHardwareAcceleration(LibVLC.HW_ACCELERATION_FULL);
libvlc.eventVideoPlayerActivityCreated(true);
libvlc.setSubtitlesEncoding("");
libvlc.setAout(LibVLC.AOUT_OPENSLES);
libvlc.setTimeStretching(true);
libvlc.setChroma("RV32");
libvlc.setVerboseMode(true);
LibVLC.restart(this);
EventHandler.getInstance().addHandler(mHandler);
holder.setFormat(PixelFormat.RGBX_8888);
holder.setKeepScreenOn(true);
mSubtitlesSurfaceHolder = mSubtitlesSurface.getHolder();
mSubtitlesSurfaceHolder.setFormat(PixelFormat.RGBA_8888);
mSubtitlesSurface.setZOrderMediaOverlay(true);
//mSubtitlesSurface.setZOrderOnTop(true);
mSubtitlesSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
mSubtitlesSurfaceHolder.addCallback(mSubtitlesSurfaceCallback);
MediaList list = libvlc.getMediaList();
list.clear();
list.add(new Media(libvlc, LibVLC.PathToURI(media)), false);
libvlc.setVolume(100);
libvlc.playIndex(0);
}
catch (Exception e)
{
Toast.makeText(this, "Could not create Vlc Player", Toast.LENGTH_LONG).show();
}
}
private void releasePlayer()
{
if (handlerSeekbar != null && runnableSeekbar != null)
{
handlerSeekbar.removeCallbacks(runnableSeekbar);
}
EventHandler.getInstance().removeHandler(mHandler);
if (libvlc == null)
{
return;
}
libvlc.stop();
libvlc.detachSurface();
holder = null;
libvlc.closeAout();
mVideoWidth = 0;
mVideoHeight = 0;
}
/**
* **********
* Events
* ***********
*/
private Handler mHandler = new MyHandler(this);
private static class MyHandler extends Handler
{
private WeakReference<FullscreenVlcPlayer> mOwner;
public MyHandler(FullscreenVlcPlayer owner)
{
mOwner = new WeakReference<FullscreenVlcPlayer>(owner);
}
#Override
public void handleMessage(Message msg)
{
FullscreenVlcPlayer player = mOwner.get();
// Player 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:
player.setSubtitles();
break;
case EventHandler.MediaPlayerPaused:
case EventHandler.MediaPlayerStopped:
default:
break;
}
}
}
}
This is not for Android, but I think could help you
/* Create a new item */
media = libvlc_media_new_path (inst, "BlackBerry.3gp");
/* Create a media player playing environement */
mediaplayer = libvlc_media_player_new_from_media (media);
/* play the media_player */
libvlc_media_player_play (mediaplayer);
//*****************************************************************************
//*****************************************************************************
//********* Subtitle section. Must be after libvlc_media_player_play **********
//*****************************************************************************
//*****************************************************************************
int temp = libvlc_video_set_subtitle_file(mediaplayer, "NewSubFile.srt");
printf("sub status=%d\n", temp);
temp = libvlc_video_set_subtitle_file(mediaplayer, "BlackBerry.srt");
printf("sub status=%d\n", temp);
int sub_count = libvlc_video_get_spu_count(mediaplayer);
printf("sub count=%d\n", sub_count);
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
//*****************************************************************************
sleep (10); /* Let it play a bit */
/* No need to keep the media now */
libvlc_media_release (media);
/* Stop playing */
libvlc_media_player_stop (mediaplayer);
/* Free the media_player */
libvlc_media_player_release (mediaplayer);

Nexus 6 and MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);

Hi I'm trying to achieve an Activity with background made from video file. The solution posted below is working on most devices, except nexus 6 Android 5.1. The video is working, is scaled but is not cropped, so aspect ratio is not preserved.
Tested with Galaxy Note, HTC One m7, Xperia Z3, Nexus 5.
Here is the code:
public class MainActivity extends ActionBarActivity implements SurfaceHolder.Callback, OnClickListener
{
private static final int VIDEO_START_HACK_DELAY = 0;
private static final String BG_VIDEO_PATH = "/raw/construction";
private SurfaceView mSurface;
private Button mTour, mLogin;
private MediaPlayer mMediaPlayer;
private Handler mHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start_main);
setupUI();
}
private void setupUI()
{
mMediaPlayer = new MediaPlayer();
mSurface = (SurfaceView) findViewById(R.id.surface);
SurfaceHolder holder = mSurface.getHolder();
holder.addCallback(this);
mTour = (Button) findViewById(R.id.tour);
mLogin = (Button) findViewById(R.id.login);
mTour.setOnClickListener(this);
mLogin.setOnClickListener(this);
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
startVideo(holder);
}
#SuppressLint("NewApi")
public void startVideo(SurfaceHolder holder)
{
String path = "android.resource://" + getPackageName() + BG_VIDEO_PATH;
Uri uri = Uri.parse(path);
try
{
android.view.ViewGroup.LayoutParams lp = mSurface.getLayoutParams();
mMediaPlayer.setDisplay(holder);
mMediaPlayer.setDataSource(this, uri);
mMediaPlayer.setVideoScalingMode(MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
mMediaPlayer.setLooping(true);
mMediaPlayer.setOnPreparedListener(new OnPreparedListener()
{
#Override
public void onPrepared(MediaPlayer mp)
{
mHandler.postDelayed(new Runnable()
{
#Override
public void run()
{
mMediaPlayer.start();
}
}, VIDEO_START_HACK_DELAY);
}
});
mMediaPlayer.prepareAsync();
}
catch (Exception e)
{
Log.e("VID", "Problem starting video bg", e);
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
// TODO Auto-generated method stub
}
#Override
public void onBackPressed()
{
mSurface.setVisibility(View.INVISIBLE);
mMediaPlayer.stop();
super.onBackPressed();
}
#Override
protected void onDestroy()
{
mMediaPlayer.stop();
mMediaPlayer.release();
super.onDestroy();
}
}
Here is layout file:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="40dp"
android:gravity="center"
android:orientation="vertical" >
<Button
android:id="#+id/tour"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:padding="10dp"
android:text="#string/ma_tour"/>
<Button
android:id="#+id/login"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="10dp"
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:text="#string/ma_log_in"/>
</LinearLayout>
</RelativeLayout>
Target sdk is set to 22.
Have you maybe experienced such behavior and can give any advice?
Here is how I did it in one of my applications:
Set the OnPreparedListener on MediaPlayer object.
mediaPlayer.setOnPreparedListener(this);
When the public void onPrepared(MediaPlayer mp) is called, resize the SurfaceView so that it creates the illusion of cropped video.
Log.v(LOG_TAG, "onPrepared called for MediaPlayer");
// Adjust the size of the video so it fits on the screen
int videoWidth = mInitialVideoPlayer.getVideoWidth();
int videoHeight = mInitialVideoPlayer.getVideoHeight();
float videoProportion = (float) videoWidth / (float) videoHeight;
ViewGroup.LayoutParams lp = mSplashVideoSurfaceView.getLayoutParams();
// We always want to fill entire view port. So, we keep the smallest dimension and proportionately
// scale the other dimension.
if (videoWidth < videoHeight) {
lp.width = UiUtils.sScreenWidth;
lp.height = (int) ((float) UiUtils.sScreenWidth / videoProportion);
} else {
lp.width = (int) (videoProportion * (float) UiUtils.sScreenHeight);If you are targetting API level 14 and above, <code>TextureView</code> allows you to play cropped video
lp.height = UiUtils.sScreenHeight;
}
Log.v(LOG_TAG, "old video size: " + videoWidth + ", " + videoHeight);
Log.v(LOG_TAG, "screen size: " + UiUtils.sScreenWidth + ", " + UiUtils.sScreenHeight);
Log.v(LOG_TAG, "new video size: " + lp.width + ", " + lp.height);
mSplashVideoSurfaceView.setLayoutParams(lp);

Android mediaplayer onSeekComplete not being called

I'm writing a media player that will stream live and on demand streams. It's mostly working, but for some reason I can't get seekTo(int) working correctly. My problem is that when I call seekTo(int) I don't get my onSeekComplete callback. I register my callback method in my onPrepared callback.
I should note that I'm also using MediaController and I've registered my MediaPlayer with MediaController. When I seek by taping the seek bar, it goes through my MediaController and I do get my onSeekComplete callback in that scenario. Here's my code.
package com.brockoli.android.hsdroid;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Point;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.ViewGroup.LayoutParams;
import android.widget.MediaController;
import android.widget.MediaController.MediaPlayerControl;
import android.widget.ProgressBar;
public class VideoPlayerActivity extends Activity implements MediaPlayer.OnPreparedListener,
MediaPlayer.OnVideoSizeChangedListener,
SurfaceHolder.Callback,
MediaController.MediaPlayerControl,
OnSeekCompleteListener {
private MediaPlayer mp;
private MediaController mc;
private int width = 0;
private int height = 0;
private SurfaceView surface;
private SurfaceHolder holder;
private ProgressBar timeline = null;
private boolean isPaused = false;
private int mCurrentPosition = 0;
private Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video_player);
if (getLastNonConfigurationInstance() != null) {
mCurrentPosition = (Integer) getLastNonConfigurationInstance();
}
mc = new MediaController(this);
surface = (SurfaceView) findViewById(R.id.surface_video);
holder = surface.getHolder();
holder.addCallback(this);
}
#Override
protected void onPause() {
super.onPause();
isPaused = true;
}
#Override
protected void onResume() {
super.onResume();
width = getScreenWidth();
height = setHeightBasedOnWidth();
isPaused = false;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mp != null) {
mp.release();
mp = null;
}
}
#Override
public Object onRetainNonConfigurationInstance() {
int currentPosition = 0;
if (mp != null && mp.isPlaying()) {
currentPosition = mp.getCurrentPosition();
}
return currentPosition;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
mc.show();
return false;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Intent intent = this.getIntent();
String url = intent.getStringExtra("STREAM_ID");
playVideo(url);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
LayoutParams lp = surface.getLayoutParams();
lp.width = width;
lp.height = height;
surface.setLayoutParams(lp);
if (width != 0 && height != 0) {
holder.setFixedSize(width, height);
mc.setMediaPlayer(this);
mc.setAnchorView(surface);
handler.post(new Runnable() {
#Override
public void run() {
mc.setEnabled(true);
mc.show();
}
});
Log.d("MEDIAPLAYER", "onPrepared start");
mp.seekTo(mCurrentPosition);
//mediaPlayer.start();
}
}
private void playVideo(String url) {
try {
if (mp == null) {
mp = new MediaPlayer();
mp.setScreenOnWhilePlaying(true);
mp.setOnVideoSizeChangedListener(this);
mp.setOnSeekCompleteListener(this);
} else {
mp.stop();
mp.reset();
}
mp.setDataSource(url);
mp.setDisplay(holder);
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setOnPreparedListener(this);
mp.prepareAsync();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onVideoSizeChanged(MediaPlayer mediaPlayer, int newWidth, int newHeight) {
/* if (width != 0 && height != 0) {
holder.setFixedSize(width, height);
//mp.seekTo(mCurrentPosition);
Log.d("MEDIAPLAYER", "onVideoSizeChanged start");
//mediaPlayer.start();
}
*/
}
private Point getScreenSize() {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
private int getScreenWidth() {
return getScreenSize().x;
}
private int getScreenHeight() {
return getScreenSize().y;
}
private int setHeightBasedOnWidth() {
if (getScreenWidth() > getScreenHeight()) {
return getScreenHeight();
}
return (int) (getScreenWidth()/1.6);
}
#Override
public boolean canPause() {
return true;
}
#Override
public boolean canSeekBackward() {
return true;
}
#Override
public boolean canSeekForward() {
return true;
}
#Override
public int getBufferPercentage() {
return 0;
}
#Override
public int getCurrentPosition() {
return mp.getCurrentPosition();
}
#Override
public int getDuration() {
return mp.getDuration();
}
#Override
public boolean isPlaying() {
return mp.isPlaying();
}
#Override
public void pause() {
mp.pause();
}
#Override
public void seekTo(int pos) {
mp.seekTo(pos);
}
#Override
public void start() {
Log.d("MEDIAPLAYER", "MediaController start");
mp.start();
}
#Override
public void onSeekComplete(MediaPlayer mp) {
mp.start();
}
}
Devices implement MediaPlayer a little differently sometimes. Check your onInfo listener to see if you're getting feedback.
Edit from comment:
I just tried it myself and it didn't work for me either in my app. The way around it for me was, especially if your media was already playing when the seek event started, if you see the currentPosition increasing again then you know that seeking has been completed.

Categories

Resources