Nexus 6 and MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING); - android

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);

Related

How to add media controller on VLC android programatically

I want to to add the media controller on VLC player android integration but i didn't find any option to do that i am sharing the code -
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.otherformat);
load = (ProgressBar) this.findViewById(R.id.load);
intent = getIntent();
load.setVisibility(View.VISIBLE);
handler = new Handler();
mFilePath ="http://mm2.pcslab.com/mm/7h800.mp4";
Log.e(TAG, "Playing: " + mFilePath);
mSurface = (SurfaceView) findViewById(R.id.surface);
holder = mSurface.getHolder();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setSize(mVideoWidth, mVideoHeight);
}
#Override
protected void onResume() {
super.onResume();
createPlayer(mFilePath);
}
#Override
protected void onPause() {
super.onPause();
releasePlayer();
}
#Override
protected void onDestroy() {
super.onDestroy();
releasePlayer();
}
/**
* Used to set size for SurfaceView
*
* #param width
* #param height
*/
private void setSize(int width, int height) {
mVideoWidth = width;
mVideoHeight = height;
if (mVideoWidth * mVideoHeight <= 1)
return;
if (holder == null || mSurface == null)
return;
int w = getWindow().getDecorView().getWidth();
int h = getWindow().getDecorView().getHeight();
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);
holder.setFixedSize(mVideoWidth, mVideoHeight);
ViewGroup.LayoutParams lp = mSurface.getLayoutParams();
lp.width = w;
lp.height = h;
mSurface.setLayoutParams(lp);
mSurface.invalidate();
}
/**
* Creates MediaPlayer and plays video
*
* #param media
*/
private void createPlayer(String media) {
releasePlayer();
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 LibVLC
// TODO: make this more robust, and sync with audio demo
ArrayList<String> options = new ArrayList<String>();
//options.add("--subsdec-encoding <encoding>");
options.add("--aout=opensles");
options.add("--audio-time-stretch"); // time stretching
options.add("-vvv"); // verbosity
libvlc = new LibVLC(this, options);
holder.setKeepScreenOn(true);
// Creating media player
mMediaPlayer = new MediaPlayer(libvlc);
mMediaPlayer.setEventListener(mPlayerListener);
mMediaPlayer.setVideoTrackEnabled(true);
// Seting up video output
final IVLCVout vout = mMediaPlayer.getVLCVout();
vout.setVideoView(mSurface);
//vout.setSubtitlesView(mSurfaceSubtitles);
vout.addCallback(this);
vout.attachViews();
Media m = new Media(libvlc, Uri.parse(media));
mMediaPlayer.setMedia(m);
mMediaPlayer.play();
////////////////////////////////////////////////
/* //mController = new MediaController(this);
mController = (MediaController)findViewById(R.id.mediaController);
mController.setVisibility(View.VISIBLE);
mController.setAnchorView(mSurface);
mController.show(0);*/
/*mController = new MediaController(this);
mController.setAnchorView(mSurface);
handler.post(new Runnable() {
public void run() {
mController.show();
}
});*/
} catch (Exception e) {
Log.e("Err", e.getMessage()+"");
Toast.makeText(this, "Error in creating player!"+e.getMessage(), Toast
.LENGTH_LONG).show();
}
}
private void releasePlayer() {
if (libvlc == null)
return;
mMediaPlayer.stop();
final IVLCVout vout = mMediaPlayer.getVLCVout();
vout.removeCallback(this);
vout.detachViews();
holder = null;
libvlc.release();
libvlc = null;
mVideoWidth = 0;
mVideoHeight = 0;
}
/**
* Registering callbacks
*/
private MediaPlayer.EventListener mPlayerListener = new MyPlayerListener(this);
#Override
public void onNewLayout(IVLCVout vout, int width, int height, int visibleWidth, int visibleHeight, int sarNum, int sarDen) {
if (width * height == 0)
return;
// store video size
mVideoWidth = width;
mVideoHeight = height;
setSize(mVideoWidth, mVideoHeight);
}
#Override
public void onSurfacesCreated(IVLCVout vout) {
}
#Override
public void onSurfacesDestroyed(IVLCVout vout) {
}
#Override
public void onHardwareAccelerationError(IVLCVout vlcVout) {
Log.e(TAG, "Error with hardware acceleration");
this.releasePlayer();
Toast.makeText(this, "Error with hardware acceleration", Toast.LENGTH_LONG).show();
}
private static class MyPlayerListener implements MediaPlayer.EventListener {
private WeakReference<OtherFormat> mOwner;
public MyPlayerListener(OtherFormat owner) {
mOwner = new WeakReference<OtherFormat>(owner);
}
#Override
public void onEvent(MediaPlayer.Event event) {
OtherFormat player = mOwner.get();
switch (event.type) {
case MediaPlayer.Event.EndReached:
Log.d(TAG, "MediaPlayerEndReached");
player.releasePlayer();
break;
case MediaPlayer.Event.Playing:
load.setVisibility(View.GONE);
break;
case MediaPlayer.Event.Paused:
case MediaPlayer.Event.Buffering:
float percent = event.getBuffering(); /* from 0.0f to 100f */
Log.e("Percent><><",""+percent);
break;
case MediaPlayer.Event.Stopped:
default:
break;
}
}
}}
XML for this activity -
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
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"
>
<SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" />
<ProgressBar
android:id="#+id/load"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:visibility="visible"
android:layout_gravity="center"
/>
<MediaController
android:id="#+id/mediaController"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
</MediaController>
</FrameLayout>
By this code mediacontrollers not showing please help me how to show media controllers for pause, play and seekbar for video position in surfaceview of vlc media player.
I had the same issue and have found a solution.
Sure, it's too late for answer, but maybe I will save some time to someone.
To add default media control you need to implement it in following way
remove MediaController from layout and add some container for media control to to your activity (it will be added programmatically).
<FrameLayout
android:id="#+id/video_surface_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:foregroundGravity="clip_horizontal|clip_vertical"
tools:ignore="true">
<SurfaceView
android:id="#+id/surface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center" />
</FrameLayout>
add controller init to onStart activity or to onCreate
import android.widget.MediaController;
private MediaController controller;
#Override
protected void onStart() {
super.onStart();
....
controller = new MediaController(this);
controller.setMediaPlayer(findViewByid(R.id.video_surface_frame));
controller.setAnchorView(mVideoSurfaceFrame);
mVideoSurfaceFrame.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
controller.show(10000);
}
});
}
to define playerInterface, you need to implement the MediaController.MediaPlayerControl interface like this
private MediaController.MediaPlayerControl playerInterface = new MediaController.MediaPlayerControl() {
public int getBufferPercentage() {
return 0;
}
public int getCurrentPosition() {
float pos = mLibVlc.getPosition();
return (int)(pos * getDuration());
}
public int getDuration() {
return (int)mLibVlc.getLength();
}
public boolean isPlaying() {
return mLibVlc.isPlaying();
}
public void pause() {
mLibVlc.pause();
}
public void seekTo(int pos) {
mLibVlc.setPosition((float)pos / getDuration());
}
public void start() {
mLibVlc.play();
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
};
launch your app and tap on video. You will see default media control and it will hide in 10 sec
Good luck!
Link to VideoLan sample on github:
https://code.videolan.org/videolan/vlc-android/blob/f3db2e4a33bf96c03056874322fb5b9304f92259/vlc-android/src/vlc/android/VLC.java
public class Show_Array extends AppCompatActivity implements IVLCVout.Callback {
private TextView container_extension;
private String stream_typee,stream_idd,container_extensionn ;
private String SAMPLE_URL = "";
public int mHeight;
public int mWidth;
private SurfaceView mVideoSurface = null;
private FrameLayout sdk;
private IVLCVout vlcVout;
private LibVLC mLibVlc = null;
private MediaPlayer mMediaPlayer = null;
private int flag = 0;
private ImageButton Resize;
private Media media;
private ArrayList<String> args;
private SurfaceHolder mSurfaceHolderVideo;
private MediaController controller;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.show__array);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
//Referances
Resize = findViewById(R.id.Resize);
mVideoSurface = findViewById(R.id.video_surface);
stream_typee = getIntent().getExtras().getString("stream_type");
stream_idd = getIntent().getExtras().getString("stream_id");
container_extensionn = getIntent().getExtras().getString("container_extension");
args = new ArrayList<>();
args.add("-vvv");
mLibVlc = new LibVLC(this, args);
mMediaPlayer = new MediaPlayer(mLibVlc);
vlcVout = mMediaPlayer.getVLCVout();
sdk = findViewById(R.id.sdk);
Resize_video();
setup_url();
controller = new MediaController(this);
controller.setMediaPlayer(playerInterface);
controller.setAnchorView(mVideoSurface);
mVideoSurface.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
controller.show(10000);
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
mMediaPlayer.release();
mLibVlc.release();
}
void Resize_video()
{
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
mHeight = displayMetrics.heightPixels;
mWidth = displayMetrics.widthPixels;
Resize.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
flag+=1;
int width = 1000;
int height = 560;
if(flag%2!=0) {
LinearLayout.LayoutParams myImageLayout = new LinearLayout.LayoutParams(width, height);
myImageLayout.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
sdk.setLayoutParams(myImageLayout);
vlcVout.setWindowSize(width,height);
}
else
{
LinearLayout.LayoutParams myImageLayout = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
myImageLayout.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
sdk.setLayoutParams(myImageLayout);
vlcVout.setWindowSize(mWidth,mHeight);
}
}
});
}
void setup_url()
{
//TextView
container_extension = findViewById(R.id.URL);
if (stream_typee.equals("live"))
{
SAMPLE_URL = "http://uautv.ru:2095/"+stream_typee+"/webserver/6tE#BzW73#sX/"+stream_idd+".ts";
container_extension.setText( SAMPLE_URL);
}else
{
SAMPLE_URL = "http://uautv.ru:2095/"+stream_typee+"/webserver/6tE#BzW73#sX/"+stream_idd+"."+container_extensionn;
container_extension.setText( SAMPLE_URL);
}
}
#Override
protected void onStart() {
super.onStart();
vlcVout.setWindowSize(mWidth,mHeight);
vlcVout.setVideoView(mVideoSurface);
vlcVout.attachViews();
mMediaPlayer.getVLCVout().addCallback(this);
if(!SAMPLE_URL.isEmpty()) {
media = new Media(mLibVlc, Uri.parse(SAMPLE_URL));
mMediaPlayer.setMedia(media);
media.release();
mMediaPlayer.play();
}else
{
Toast.makeText(getApplicationContext(),"URL EMPTY",Toast.LENGTH_LONG).show();
}
}
#Override
protected void onStop() {
super.onStop();
mMediaPlayer.stop();
mMediaPlayer.getVLCVout().detachViews();
mMediaPlayer.getVLCVout().removeCallback(this);
}
#TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public void onNewLayout(IVLCVout vlcVout, int width, int height, int visibleWidth, int visibleHeight, int sarNum, int sarDen)
{ }
#Override
public void onSurfacesCreated(IVLCVout vlcVout) {
}
#Override
public void onSurfacesDestroyed(IVLCVout vlcVout) {
}
private MediaController.MediaPlayerControl playerInterface = new MediaController.MediaPlayerControl() {
public int getBufferPercentage() {
return 0;
}
public int getCurrentPosition() {
float pos = mMediaPlayer.getPosition();
return (int)(pos * getDuration());
}
public int getDuration() {
return (int)mMediaPlayer.getLength();
}
public boolean isPlaying() {
return mMediaPlayer.isPlaying();
}
public void pause() {
mMediaPlayer.pause();
}
public void seekTo(int pos) {
mMediaPlayer.setPosition((float)pos / getDuration());
}
public void start() {
mMediaPlayer.play();
}
public boolean canPause() {
return true;
}
public boolean canSeekBackward() {
return true;
}
public boolean canSeekForward() {
return true;
}
#Override
public int getAudioSessionId() {
return 0;
}
};
}

Video initialization take too long in background

It takes too long to start a video and in the console I get this error again and again until the video finally start:
I/NuPlayerRenderer: possible video time jump of 0ms or uninitialized media clock, retrying in 100ms
Here is my Activity class:
public class EntryView extends AppCompatActivity implements SurfaceHolder.Callback {
SurfaceView imageLogo;
MediaPlayer mp;
#Override
protected void attachBaseContext(Context newBase) {
ContextWrapper contextWrapper = CalligraphyContextWrapper.wrap(newBase);
super.attachBaseContext(contextWrapper);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
overridePendingTransition(0, 0);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_entry);
imageLogo = (SurfaceView) findViewById(R.id.image_logo);
imageLogo.getHolder().addCallback(this);
mp = new MediaPlayer();
ButterKnife.bind(this);
}
// UI CALLBACKS ------------------------------------------------------------------------------
#OnClick({R.id.button_login, R.id.button_register_normal})
void openScreen(View v) {
Intent intent = null;
switch (v.getId()) {
case R.id.button_login:
intent = new Intent(EntryView.this, LoginView.class);
break;
case R.id.button_register_normal:
intent = new Intent(EntryView.this, RegisterView.class);
break;
}
startActivity(intent);
overridePendingTransition(R.anim.slide_in_from_right, R.anim.scale_out);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
Uri video = Uri.parse("android.resource://" + getPackageName() + "/"
+ R.raw.sample);
try {
mp.setDataSource(this, video);
mp.prepare();
} catch (IOException e) {
e.printStackTrace();
}
//Get the dimensions of the video
int videoWidth = mp.getVideoWidth();
int videoHeight = mp.getVideoHeight();
//Get the width of the screen
int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
//Get the SurfaceView layout parameters
android.view.ViewGroup.LayoutParams lp = imageLogo.getLayoutParams();
//Set the width of the SurfaceView to the width of the screen
lp.width = screenWidth;
//Set the height of the SurfaceView to match the aspect ratio of the video
//be sure to cast these as floats otherwise the calculation will likely be 0
lp.height = (int) (((float)videoHeight / (float)videoWidth) * (float)screenWidth);
//Commit the layout parameters
imageLogo.setLayoutParams(lp);
//Start video
mp.setDisplay(holder);
mp.setLooping(true);
mp.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
And this is the xml file:
<android.support.percent.PercentRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.omnidoctor.omniapp.screens.entry.EntryView">
<SurfaceView
android:id="#+id/image_logo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dip"/>
<View
android:id="#+id/spacer"
android:layout_marginTop="85dp"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_heightPercent="20%" />
<Button
android:id="#+id/button_register_normal"
fontPath="fonts/Arciform.ttf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/spacer"
android:background="#drawable/background_button_white"
android:minHeight="20dp"
android:paddingBottom="20dp"
android:paddingTop="20dp"
android:text="#string/register_normal_text"
android:textAllCaps="false"
android:textColor="#color/state_color_blue"
android:textSize="16sp"
app:layout_marginLeftPercent="10%"
app:layout_marginRightPercent="10%"
tools:ignore="MissingPrefix" />
<Button
android:id="#+id/button_login"
fontPath="fonts/Arciform.ttf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="#id/button_register_normal"
android:layout_marginTop="14dp"
android:minHeight="20dp"
android:minWidth="0dp"
android:textColor="#color/state_color_blue"
android:background="#drawable/background_button_white"
android:paddingBottom="20dp"
android:paddingTop="20dp"
android:text="#string/log_in"
android:textAllCaps="false"
android:textSize="15sp"
app:layout_marginLeftPercent="10%"
app:layout_marginRightPercent="10%"
tools:ignore="MissingPrefix" />
</android.support.percent.PercentRelativeLayout>
As you can see I am using a SurfaceView but I tried as well with VideoView and I get the same problem. The video just have 1,5MB for and it takes 30 seconds so it is not a really big one.
EDIT
I forgot to tell that is a mp4 video. I am not sure if this has something to do but just in case.

Recording video in Android changes

I have a small problem when recording a video on my phone. I have followed this example to learn and get inspired:
http://examples.javacodegeeks.com/android/core/android-video-capture-example/
Based on that ( btw a good example), it seems that when recording a video, it changes the aspect a little bit but I want to avoid that.
Any advice?
Android code:
public class VideoPreivewFragment extends Fragment implements TextureView.SurfaceTextureListener, OnClickListener {
#InjectView(R.id.preview_movie)
TextureView mTextureView;
#InjectView(R.id.video_play_button)
ImageButton mButtonVideoPlay;
#InjectView(R.id.playMovie_afl)
AspectFrameLayout layout;
private MediaPlayer mMediaPlayer;
float mVideoHeight, mVideoWidth;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View viewRoot = inflater.inflate(R.layout.video_preview_screen, container, false);
ButterKnife.inject(this, viewRoot);
calculateVideoSize();
mTextureView.setSurfaceTextureListener(this);
Backendless.setUrl("https://api.backendless.com");
return viewRoot;
}
private void calculateVideoSize() {
try {
String videopath = ((VideoPreviewActivity) getActivity()).
fragmentArgumentToIntent(getArguments()).getStringExtra(Constants.TEMP_VIDEOPATH);
MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
metaRetriever.setDataSource(videopath);
String height = metaRetriever
.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
String width = metaRetriever
.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
mVideoHeight = Float.parseFloat(height);
mVideoWidth = Float.parseFloat(width);
} catch (Exception e) {
}
}
private void adjustAspectRatio(float videoWidth, float videoHeight) {
int viewWidth = layout.getWidth();
int viewHeight = layout.getHeight();
double aspectRatio = (double) videoHeight / videoWidth;
int newWidth, newHeight;
if (viewHeight > (int) (viewWidth * aspectRatio)) {
// limited by narrow width; restrict height
newWidth = viewWidth;
newHeight = (int) (viewWidth * aspectRatio);
} else {
// limited by short height; restrict width
newWidth = (int) (viewHeight / aspectRatio);
newHeight = viewHeight;
}
int xoff = (viewWidth - newWidth) / 2;
int yoff = (viewHeight - newHeight) / 2;
Matrix txform = new Matrix();
mTextureView.getTransform(txform);
txform.setScale((float) newWidth / viewWidth, (float) newHeight / viewHeight);
//txform.postRotate(10); // just for fun
txform.postTranslate(xoff, yoff);
mTextureView.setTransform(txform);
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onResume() {
super.onResume();
}
#Override
public void onPause() {
ButterKnife.reset(this);
super.onPause();
}
#Override
public void onStop() {
ButterKnife.reset(this);
super.onStop();
}
#Override
public void onDestroy() {
ButterKnife.reset(this);
if (mMediaPlayer != null) {
// Make sure we stop video and release resources when activity is destroyed.
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
super.onDestroy();
}
#Override
public void onDetach() {
super.onDetach();
}
#Override
#OnClick({R.id.preview_movie, R.id.video_play_button})
public void onClick(View view) {
if (view.getId() == R.id.video_play_button) {
} else if (view.getId() == R.id.preview_movie) {
if(mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
}
else {
mMediaPlayer.start();
}
}
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
Surface surface = new Surface(surfaceTexture);
try {
String videopath = ((VideoPreviewActivity) getActivity()).
fragmentArgumentToIntent(getArguments()).getStringExtra(Constants.TEMP_VIDEOPATH);
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(videopath);
mMediaPlayer.setSurface(surface);
// don't forget to call MediaPlayer.prepareAsync() method when you use constructor for
// creating MediaPlayer
mMediaPlayer.prepareAsync();
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
int videoWidth = mMediaPlayer.getVideoWidth();
int videoHeight = mMediaPlayer.getVideoHeight();
DisplayMetrics displayMetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int screenWidth = displayMetrics.widthPixels;
int screenHeight = displayMetrics.heightPixels;
float videoProportion = (float) videoWidth / (float) videoHeight;
float screenProportion = (float) screenWidth / (float) screenHeight;
ViewGroup.LayoutParams lp = layout.getLayoutParams();
if (videoProportion > screenProportion) {
lp.width = screenWidth;
lp.height = (int) (videoProportion * (float) screenHeight);
lp.height = screenHeight;
}
layout.setLayoutParams(lp);
mediaPlayer.start();
}
});
mTextureView.setFitsSystemWindows(true);
} catch (IllegalArgumentException | IllegalStateException | SecurityException | IOException e) {
}
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
}
}
layout file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.awesome.kkh.theelevator.layout.AspectFrameLayout
android:id="#+id/playMovie_afl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/control"
android:layout_centerInParent="true" >
<TextureView
android:id="#+id/preview_movie"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:layout_gravity="center"
/>
</com.awesome.kkh.theelevator.layout.AspectFrameLayout>
<FrameLayout
android:id="#+id/control"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:background="#color/color_darker_background">
<ImageButton
android:id="#+id/video_play_button"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_gravity="center"
android:background="#drawable/circlebutton"
android:src="#drawable/ic_fa_play" />
</FrameLayout>
</RelativeLayout>

Using surfaceview and fragments to display video. Video doesn't show but I have sound,

I have seen several posts with the same issue, but I still can't fix my issue. I am using surfaceview, fragments and mediaplayer to play a mp4 video. I get audio, but no video. The video does play with no issues outside of the application. I have tried different formats, but no luck. I am not using an emulator. I am using a Samsung Galaxy Tab2 to test. What am I missing to show video?
Here is my XML file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<SurfaceView
android:id="#+id/video_surfaceView"
android:layout_weight="1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</SurfaceView>
<Button
android:id="#+id/playvideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PLAY "/>
<Button
android:id="#+id/pausevideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- PAUSE"/>
<Button
android:id="#+id/stopvideoplayer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="- STOP"/>
</LinearLayout>
Here is my code:
public class ChapterVideoFragment extends Fragment {
private static final String TAG = "ChapterVideoFragment";
private static final boolean VERBOSE = true;
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private MediaPlayer mp = null;
private Button mPlayVideo,
mPauseVideo,
mStopVideo;
private boolean mPausing = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
if (VERBOSE) Log.v(TAG, "+++ onCreateView +++");
View v = inflater.inflate(R.layout.fragment_video, parent, false);
mSurfaceView = (SurfaceView)v.findViewById(R.id.video_surfaceView);
mPlayVideo = (Button)v.findViewById(R.id.playvideoplayer);
mPauseVideo = (Button)v.findViewById(R.id.pausevideoplayer);
mStopVideo = (Button)v.findViewById(R.id.stopvideoplayer);
mp = MediaPlayer.create(getActivity(), R.raw.improvisation);
mPlayVideo.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
//Get the dimensions of the video
int videoWidth = mp.getVideoWidth();
int videoHeight = mp.getVideoHeight();
//Get the width of the screen
int screenWidth =
getActivity().getWindowManager().getDefaultDisplay().getWidth();
//Get the SurfaceView layout parameters
android.view.ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
//Set the width of the SurfaceView to the width of the screen
lp.width = screenWidth;
//Set the height of the SurfaceView to match the aspect ratio of the video
//be sure to cast these as floats otherwise the calculation will likely be
0
lp.height = (int) (((float)videoHeight / (float)videoWidth) *
(float)screenWidth);
//Commit the layout parameters
mSurfaceView.setLayoutParams(lp);
//mp.setDisplay(mSurfaceView.getHolder());
mp.start();
}
});
Here is the code for SurfaceView:
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
if (VERBOSE) Log.v(TAG, "+++ surfaceCreated +++");
// TODO Auto-generated method stub
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
});
try using videoview - it is possible that the device you are using to display the video, does not support the format in mediaplayer object, i solved this problem with videoview

Android MediaPlayer does not display video, only play audio

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()

Categories

Resources