surfaceview playing video as stretched view
Asked Answered
S

2

3

I am using the mediaplayer.xml to play the video file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/MainView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#4d4d4d"
android:gravity="center"
android:keepScreenOn="true"
android:orientation="vertical" >

<SurfaceView
   android:id="@+id/surfaceView"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:layout_gravity="center"
   />

</LinearLayout>

The following MediaPlayerActivity class using SurfaceView and MediaPlayer While playing video in portrait mode it seems that the video stretched one. I want to play the video vertically center and should not occupy the full screen and then in landscape mode should play in full screen mode.

public class MediaPlayerActivity extends Activity implements OnCompletionListener,
OnErrorListener, OnInfoListener, OnBufferingUpdateListener,
OnPreparedListener, OnSeekCompleteListener, SurfaceHolder.Callback,
MediaController.MediaPlayerControl {

private MediaController controller;
Display currentDisplay;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private MediaPlayer mediaPlayer;

int videoWidth = 0;
int videoHeight = 0;
boolean readyToPlay = false;

private String streamingVideoUrl;

private ProgressDialog dialog;

public final  String TAG = "VIDEO_PLAYER";

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    Log.d(TAG,"Media player activity called ");
    setContentView(R.layout.mediaplayer);

    if(getIntent() != null ){
        streamingVideoUrl = getIntent().getStringExtra("stream_url"); 
    }

    surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
    surfaceView.setOnClickListener(surViewClickListener);

    surfaceHolder = surfaceView.getHolder();

    surfaceHolder.addCallback(this);

    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    /*setVideoSize();*/
    try {
    mediaPlayer = new MediaPlayer();

    mediaPlayer.setOnCompletionListener(this);
    mediaPlayer.setOnErrorListener(this);
    mediaPlayer.setOnInfoListener(this);
    mediaPlayer.setOnPreparedListener(this);
    mediaPlayer.setOnSeekCompleteListener(this);


    mediaPlayer.setOnBufferingUpdateListener(this);
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    //Log.d(TAG,"Returned by getDatasource :"+getDataSource(streamingVideoUrl));
        mediaPlayer.setDataSource(streamingVideoUrl);
    } catch (IllegalArgumentException e) {

        e.printStackTrace();
    } catch (SecurityException e) {

        e.printStackTrace();
    } catch (IllegalStateException e) {

        e.printStackTrace();
    } catch (IOException e) {

        e.printStackTrace();
    }

    catch(Exception e)
    {
        e.printStackTrace();
    }

    currentDisplay = getWindowManager().getDefaultDisplay();
    controller = new MediaController(this);

    dialog = new ProgressDialog(this);
    //dialog.setMessage("Preparing File to Streaming");
    dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    dialog.setCanceledOnTouchOutside(false);
    if(this!= null && !this.isFinishing()){

        dialog.show();
    }

    handler.postDelayed(r, 100);
}

/*private void setVideoSize() {


    try {
        // // Get the dimensions of the video
        int videoWidth = mediaPlayer.getVideoWidth();
        int videoHeight = mediaPlayer.getVideoHeight();
        float videoProportion = (float) videoWidth / (float) videoHeight;

        // Get the width of the screen
        int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
        int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
        float screenProportion = (float) screenWidth / (float) screenHeight;

        // Get the SurfaceView layout parameters
        android.view.ViewGroup.LayoutParams lp = surfaceView.getLayoutParams();
        if (videoProportion > screenProportion) {
            lp.width = screenWidth;
            lp.height = (int) ((float) screenWidth / videoProportion);
        } else {
            lp.width = (int) (videoProportion * (float) screenHeight);
            lp.height = screenHeight;
        }
        // Commit the layout parameters
        surfaceView.setLayoutParams(lp);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}*/


/*//coded by Karthikeyan V
    //converting url to byte 
    private String getDataSource(String path) throws IOException {
        Log.d(TAG,"getDataSource called");
        if (!URLUtil.isNetworkUrl(path)) {
            return path;
        } else {
            URL url = new URL(path);
            URLConnection cn = url.openConnection();
            cn.connect();
            InputStream stream = cn.getInputStream();
            if (stream == null)
                throw new RuntimeException("stream is null");
            File temp = File.createTempFile("mediaplayertmp", "dat");
            temp.deleteOnExit();
            String tempPath = temp.getAbsolutePath();
            FileOutputStream out = new FileOutputStream(temp);
            byte buf[] = new byte[128];
            do {
                int numread = stream.read(buf);
                if (numread <= 0)
                    break;
                out.write(buf, 0, numread);
            } while (true);
            try {
                stream.close();
            } catch (IOException ex) {
                Log.e(TAG, "error: " + ex.getMessage(), ex);
            }
            Log.d(TAG,"temp path :"+tempPath);
            return tempPath;
        }
    }*/


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

    if(mediaPlayer !=null)
        return mediaPlayer.getCurrentPosition();
    else 
        return 0;
}

@Override
public int getDuration() {

    return mediaPlayer.getDuration();
}

@Override
public boolean isPlaying() {

    return mediaPlayer.isPlaying();
}

@Override
public void pause() {

    if (mediaPlayer != null) {
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }
}

@Override
public void seekTo(int pos) {

    mediaPlayer.seekTo(pos);
}

@Override
public void start() {

    mediaPlayer.start();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
        int height) {
    if(Constants.DEBUG)
        Log.v(TAG, "Media Flow surfaceChanged Called");
} 
@Override
public void surfaceCreated(SurfaceHolder holder) {

    if(Constants.DEBUG)
        Log.v(TAG, "Media Flow surfaceCreated Called");
    mediaPlayer.setDisplay(holder);

    try {
        mediaPlayer.prepareAsync();
    } catch (IllegalStateException e) {
        if(Constants.DEBUG)
            Log.v(TAG, "Media Flow IllegalStateException " + e.getMessage());
        finish();
    }

    if(Constants.DEBUG)
        Log.d(TAG, "Media Flow MediaPlayer Preparing");

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
    if(Constants.DEBUG)
        Log.v(TAG, "Media Flow surfaceDestroyed Called");
}


@Override
public void onSeekComplete(MediaPlayer mp) {
    if(Constants.DEBUG)
        Log.v(TAG, "Media Flow onSeekComplete Called");
}

@Override
public void onPrepared(MediaPlayer mp) {

    if(Constants.DEBUG)
        Log.v(TAG, "Media Flow onPrepared Called");

    // dismissProgressLoading();

    controller.setMediaPlayer(this);
    controller.setAnchorView(this.findViewById(R.id.MainView));
    controller.setEnabled(true);
    controller.show();
    mp.start();

}

@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {

    if(Constants.DEBUG)
        Log.v(TAG, "Media Flow MediaPlayer Buffering: " + percent + "%");
    dismissProgressLoading();
}

@Override
public boolean onInfo(MediaPlayer mp, int whatInfo, int extra) {
    // 
    dismissProgressLoading();

    if(Constants.DEBUG)
    {
        if (whatInfo == MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING) {
            if(Constants.DEBUG)
                Log.v(TAG, "Media Flow Media Info, Media Info Bad Interleaving " + extra);
        } else if (whatInfo == MediaPlayer.MEDIA_INFO_NOT_SEEKABLE) {
            if(Constants.DEBUG)
                Log.v(TAG, "Media Flow Media Info, Media Info Not Seekable " + extra);
        } else if (whatInfo == MediaPlayer.MEDIA_INFO_UNKNOWN) {
            Log.v(TAG, "Media Flow Media Info, Media Info Unknown " + extra);
        } else if (whatInfo == MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING) {
            Log.v(TAG, "Media Flow MediaInfo, Media Info Video Track Lagging " + extra);
        } else if (whatInfo == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) {
            Log.v(TAG, "Media Flow MediaInfo, Media Info Metadata Update " + extra);
        }
    }

    return false;
}

@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
    // TODO Auto-generated method stub

    dismissProgressLoading();

    StringBuilder sb = new StringBuilder();
    sb.append("Media Player Error: ");
    switch (what) {
    case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
        sb.append("Not Valid for Progressive Playback");
        break;
    case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
        sb.append("Server Died");
        break;
    case MediaPlayer.MEDIA_ERROR_UNKNOWN:
        sb.append("Media Error Unknown");
        break;
    default:
        sb.append(" Non standard (");
        sb.append(what);
        sb.append(")");
    }
    //sb.append(" (" + what + ") ");
    sb.append(extra);

    showErrorDialog("Cannot play video", sb.toString());


    return true;
}

void dismissProgressLoading() {
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
    }
}

@Override
public void onCompletion(MediaPlayer mp) {
    if(Constants.DEBUG)
    Log.v(TAG, "Media Flow onCompletion Called");
    dismissProgressLoading();
    onBackPressed();
}


@Override
public void onBackPressed() {
    // TODO Auto-generated method stub
    super.onBackPressed();
}


final Runnable r = new Runnable() {
    public void run() {

        if (mediaPlayer != null) {
            if (mediaPlayer.isPlaying()
                    && mediaPlayer.getCurrentPosition() > 0) {
                if(Constants.DEBUG)
                Log.d(TAG, "isPlaying : " + mediaPlayer.isPlaying());
                if(Constants.DEBUG)
                Log.d(TAG,
                        "currentPosition : "
                                + mediaPlayer.getCurrentPosition());

                handler.sendEmptyMessage(0);
            } else {
                handler.postDelayed(this, 100);
            }
        }
    }
};

Handler handler = new Handler() {

    public void handleMessage(Message msg) {
        dismissProgressLoading();
    }

};

@Override
protected void onResume() {

    if(Constants.SHOULD_FINISH_APPLICATION)
        finish();
    super.onResume();
}

@Override
protected void onRestart() {        
    super.onRestart();

}

protected void onPause() {
    super.onPause();
    pause();
}

@Override
protected void onDestroy() {

    super.onDestroy();

    dismissProgressLoading();

    if (mediaPlayer != null) {
        mediaPlayer.stop();
        mediaPlayer.release();
        mediaPlayer = null;
    }
    if(controller !=null)
    {
        controller.hide();
    }
}

OnClickListener surViewClickListener = new OnClickListener() {

    @Override
    public void onClick(View v) {


        if (controller != null) {
            if (controller.isShowing()) {
                controller.hide();

            } else {
                controller.show();

            }
        }
    }
};

@SuppressWarnings("deprecation")
void showErrorDialog(String title, String message) {
    AlertDialog alertDialog = new AlertDialog.Builder(this).create();

    // Setting Dialog Title
    alertDialog.setTitle(title);

    // Setting Dialog Message
    alertDialog.setMessage(message);

    // Setting Icon to Dialog
    alertDialog.setIcon(android.R.drawable.ic_dialog_alert);

    // Setting OK Button
    alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dialog, int which) {
            // Write your code here to execute after dialog closed

            dialog.dismiss();
            finish();
        }
    });


    // Showing Alert Message
    if(this!= null && !this.isFinishing()){
        alertDialog.show();
    }


}

}

Satan answered 18/1, 2014 at 10:36 Comment(3)
Any chance that you find a solution to this? Im struggeling with the same issue. Can fix then preview, but then my recorder fails on stopAluino
@Aluino I have used VideoView instead of SurfaceView. I am not sure that it is a right solution. And I haven't implement the recorder option.Satan
Great stuff, thanks for letting me know buddy! Haven't look at VideoView yet, will definitely be worth looking into. always good to learn something newAluino
B
3

I met the same problem,after i look into VideoView source code in API 23,i found the good method,here is my solution,we can create a custom SurfaceView and override onMeasure(),then here you go,use VideoSurfaceView to play the video.

public class VideoSurfaceView extends SurfaceView implements MediaPlayer.OnVideoSizeChangedListener {
    private int mVideoWidth;
    private int mVideoHeight;

    public VideoSurfaceView(Context context) {
        super(context);
    }

    public VideoSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * Set video size.
     *
     * @see MediaPlayer#getVideoWidth()
     * @see MediaPlayer#getVideoHeight()
     */
    public void setVideoSize(int videoWidth, int videoHeight) {
        mVideoWidth = videoWidth;
        mVideoHeight = videoHeight;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //Log.i("@@@@", "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
        //        + MeasureSpec.toString(heightMeasureSpec) + ")");

        int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
        int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
        if (mVideoWidth > 0 && mVideoHeight > 0) {

            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

            if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
                // the size is fixed
                width = widthSpecSize;
                height = heightSpecSize;

                // for compatibility, we adjust size based on aspect ratio
                if (mVideoWidth * height < width * mVideoHeight) {
                    //Log.i("@@@", "image too wide, correcting");
                    width = height * mVideoWidth / mVideoHeight;
                } else if (mVideoWidth * height > width * mVideoHeight) {
                    //Log.i("@@@", "image too tall, correcting");
                    height = width * mVideoHeight / mVideoWidth;
                }
            } else if (widthSpecMode == MeasureSpec.EXACTLY) {
                // only the width is fixed, adjust the height to match aspect ratio if possible
                width = widthSpecSize;
                height = width * mVideoHeight / mVideoWidth;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    // couldn't match aspect ratio within the constraints
                    height = heightSpecSize;
                }
            } else if (heightSpecMode == MeasureSpec.EXACTLY) {
                // only the height is fixed, adjust the width to match aspect ratio if possible
                height = heightSpecSize;
                width = height * mVideoWidth / mVideoHeight;
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    // couldn't match aspect ratio within the constraints
                    width = widthSpecSize;
                }
            } else {
                // neither the width nor the height are fixed, try to use actual video size
                width = mVideoWidth;
                height = mVideoHeight;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    // too tall, decrease both width and height
                    height = heightSpecSize;
                    width = height * mVideoWidth / mVideoHeight;
                }
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    // too wide, decrease both width and height
                    width = widthSpecSize;
                    height = width * mVideoHeight / mVideoWidth;
                }
            }
        } else {
            // no size yet, just adopt the given spec sizes
        }
        setMeasuredDimension(width, height);
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        mVideoWidth = mp.getVideoWidth();
        mVideoHeight = mp.getVideoHeight();
        if (mVideoWidth != 0 && mVideoHeight != 0) {
            getHolder().setFixedSize(mVideoWidth, mVideoHeight);
            requestLayout();
        }
    }
}
Bonnybonnyclabber answered 12/11, 2015 at 11:34 Comment(0)
B
6
handleAspectRatio() {
    int surfaceView_Width = surfaceView.getWidth();
    int surfaceView_Height = surfaceView.getHeight();

    float video_Width = mediaPlayer.getVideoWidth();
    float video_Height = mediaPlayer.getVideoHeight();

    float ratio_width = surfaceView_Width/video_Width;
    float ratio_height = surfaceView_Height/video_Height;
    float aspectratio = video_Width/video_Height;

    LayoutParams layoutParams = surfaceView.getLayoutParams();

    if (ratio_width > ratio_height){
        layoutParams.width = (int) (surfaceView_Height * aspectratio);
        layoutParams.height = surfaceView_Height;
    }else{
        layoutParams.width = surfaceView_Width;
        layoutParams.height = (int) (surfaceView_Width / aspectratio);
    }

    surfaceView.setLayoutParams(layoutParams);
}

call above function before calling

mediaPlayer.start();
Bung answered 31/7, 2015 at 13:9 Comment(0)
B
3

I met the same problem,after i look into VideoView source code in API 23,i found the good method,here is my solution,we can create a custom SurfaceView and override onMeasure(),then here you go,use VideoSurfaceView to play the video.

public class VideoSurfaceView extends SurfaceView implements MediaPlayer.OnVideoSizeChangedListener {
    private int mVideoWidth;
    private int mVideoHeight;

    public VideoSurfaceView(Context context) {
        super(context);
    }

    public VideoSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public VideoSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * Set video size.
     *
     * @see MediaPlayer#getVideoWidth()
     * @see MediaPlayer#getVideoHeight()
     */
    public void setVideoSize(int videoWidth, int videoHeight) {
        mVideoWidth = videoWidth;
        mVideoHeight = videoHeight;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //Log.i("@@@@", "onMeasure(" + MeasureSpec.toString(widthMeasureSpec) + ", "
        //        + MeasureSpec.toString(heightMeasureSpec) + ")");

        int width = getDefaultSize(mVideoWidth, widthMeasureSpec);
        int height = getDefaultSize(mVideoHeight, heightMeasureSpec);
        if (mVideoWidth > 0 && mVideoHeight > 0) {

            int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

            if (widthSpecMode == MeasureSpec.EXACTLY && heightSpecMode == MeasureSpec.EXACTLY) {
                // the size is fixed
                width = widthSpecSize;
                height = heightSpecSize;

                // for compatibility, we adjust size based on aspect ratio
                if (mVideoWidth * height < width * mVideoHeight) {
                    //Log.i("@@@", "image too wide, correcting");
                    width = height * mVideoWidth / mVideoHeight;
                } else if (mVideoWidth * height > width * mVideoHeight) {
                    //Log.i("@@@", "image too tall, correcting");
                    height = width * mVideoHeight / mVideoWidth;
                }
            } else if (widthSpecMode == MeasureSpec.EXACTLY) {
                // only the width is fixed, adjust the height to match aspect ratio if possible
                width = widthSpecSize;
                height = width * mVideoHeight / mVideoWidth;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    // couldn't match aspect ratio within the constraints
                    height = heightSpecSize;
                }
            } else if (heightSpecMode == MeasureSpec.EXACTLY) {
                // only the height is fixed, adjust the width to match aspect ratio if possible
                height = heightSpecSize;
                width = height * mVideoWidth / mVideoHeight;
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    // couldn't match aspect ratio within the constraints
                    width = widthSpecSize;
                }
            } else {
                // neither the width nor the height are fixed, try to use actual video size
                width = mVideoWidth;
                height = mVideoHeight;
                if (heightSpecMode == MeasureSpec.AT_MOST && height > heightSpecSize) {
                    // too tall, decrease both width and height
                    height = heightSpecSize;
                    width = height * mVideoWidth / mVideoHeight;
                }
                if (widthSpecMode == MeasureSpec.AT_MOST && width > widthSpecSize) {
                    // too wide, decrease both width and height
                    width = widthSpecSize;
                    height = width * mVideoHeight / mVideoWidth;
                }
            }
        } else {
            // no size yet, just adopt the given spec sizes
        }
        setMeasuredDimension(width, height);
    }

    @Override
    public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
        mVideoWidth = mp.getVideoWidth();
        mVideoHeight = mp.getVideoHeight();
        if (mVideoWidth != 0 && mVideoHeight != 0) {
            getHolder().setFixedSize(mVideoWidth, mVideoHeight);
            requestLayout();
        }
    }
}
Bonnybonnyclabber answered 12/11, 2015 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.