SurfaceView 将视频播放为拉伸视图

2024-07-04

我正在使用 mediaplayer.xml 来播放视频文件

<?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>

下面的MediaPlayerActivity类使用SurfaceView和MediaPlayer 在纵向模式下播放视频时,视频似乎被拉伸了。我想垂直居中播放视频,并且不应该占据全屏,然后在横向模式下应该以全屏模式播放。

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


}

}


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

在调用之前调用上面的函数

mediaPlayer.start();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SurfaceView 将视频播放为拉伸视图 的相关文章

  • 是否可以制作固定的评级栏?

    我正在从网络上获取评级 并希望通过评级栏显示评级 但我的问题是 当我滑动评级栏时 评级栏的评级会发生变化 我希望评级是固定的 并且不会因用户的触摸而改变 有人可以限制对评级栏的控制吗 我怎样才能做到这一点 Use android isInd
  • 在 Android studio 中看不到“font”资源类型

    我正在研究新的 Android O 功能 其中一项新功能是现在应用程序可以直接将字体添加到res文件夹 按照安卓文档 https developer android com preview features working with fon
  • 如何处理单个 Activity 的多个 Fragment

    我最近开始考虑为我的 Android 设备开发应用程序 我产生这种兴趣的原因是我在玩几个arduinos时想到了一个好主意 让它们与我的手机进行通信 就像我在arduino本身上测量的任何值的接口一样 现在 我可以采取简单的方法并使用公共资
  • 如何知道活动何时安排?

    我有一个地图视图 我想在其上放置一些标记 当我开始活动时 我将从网络服务中检索这些数据 因此我需要知道当前视口的最小和最大纬度 经度对 我正在打电话 mMapView getWidth mMapView getHeight 但当活动开始时它
  • 不适当的阻塞方法调用,但挂起函数“withContext”只能从协程或另一个挂起函数调用

    在我的服务中 我需要致电onStartCommand一些需要的方法withContext Dispatchers IO 反而CoroutineScope Dispatchers IO like url URL pokemon linkIma
  • 使用带有离子和电容器的 https 加载 webview

    我正在尝试构建一个必须加载的 apkhttps mydomain https mydomain与离子4和电容器 在 Capacitor config json 中 我精确了这个字段 server hostname mydomain 因为我在
  • 如何使用 Android Volley 显示/请求 JSON 对象?

    我在 Android Studio 中遇到如何请求 JSON 对象的问题 我的 Logcat 只能打印 String onResponse 而不能打印 JSONObject 值 我在 AccessActivity java 内的 try 行
  • RecyclerView 仅显示 Firebase 中的一项

    我知道关于这个问题的疑问很少 但他们都没有解决我的问题 特别是我的代码是用 Kotlin 编写的 并且是新的Fragments 不要急于说我的问题是重复的 我的问题正是标题所说的 我的RecyclerView仅填充了来自的一项 子项 Fir
  • 仅第一行断点有效

    I am developing in Android Studio i ve used IntelliJ IDEA SDK I ve encountered debugging problem All my breakpoints don
  • HTC Desire 上的 EGLConfig,可用配置挂起设备

    我正在实施我自己的EGLConfigChooser传递给setEGLConfigChooser 为了根据我对应用程序的需求为当前设备选择最佳的可用配置 更具体地说 我正在查询所有可用的配置并选择具有最大深度缓冲区大小的配置 在具有相同深度缓
  • 在Android中单击按钮后使布局出现动画

    我正在尝试为登录屏幕实现一个简单的动画效果 这是场景 1 默认情况下将显示一些文本和登录按钮 2 单击登录按钮后 将从下到上出现一个新的框架布局 此布局将提示用户输入用户名和密码 我可以制作一个动画 该动画将从一个父级覆盖到另一个父级 在这
  • getInstance() 不适用于实时数据库中除 us-central1 之外的其他位置

    我正在尝试将用户凭据保存到 Firebase 实时数据库 但是 当我执行该程序时 数据库没有更新 我已正确配置 Firebase 设置 因为身份验证和存储 均为 Firebase 正在运行 build gradle dependencies
  • Android onBackPressed() 没有被调用?

    在我的 MainActivity 从 AppCompatActivity 扩展 中 我想重写 onBackPressed 方法 如下所示 Override public void onBackPressed Log d MainActivi
  • 在 TextInputLayout 中显示密码图标触及基线

    I had some problem with my show password icon in TextInputLayout with android inputType textPassword Right now it is sho
  • 如何将node.js应用程序转换为cordova

    我们建造了一个node js适用于台式机和平板电脑的应用程序 它是完全基于网络的应用程序 现在我计划在中实现与本机应用程序相同的应用程序android using Apache cordova 在项目目录下 我们有node modules
  • 读取 NFC 标签时出现奇怪的字符

    我正在尝试使用 Android 读取 NFC 标签 我是一名养蜂人 这是为了在我接近蜂巢时识别它们 我已经在这里搜索过 但阅读标签时仍然遇到问题 我想阅读文本 但是当它阅读时 在所需文本之前有一个类似正方形的字符和显示为 十 的字符 这是我
  • 以编程方式将项目添加到相对布局

    我一直在到处寻找这个问题的答案 我是 Android 新手 尝试通过 java 而不是 xml 以编程方式将项目添加到相对布局 我创建了一个测试类来尝试一下 但项目不断堆叠而不是正确格式化 我现在只想将一个 TextView 放在另一个下面
  • 在带有效果的 Android 按钮中使用图像

    现在我在 StackOverflow 上遇到了相关问题 但不幸的是没有一个解决方案对我有用 这就是为什么我不得不单独问这个问题 我是 Android 新手 问题 我需要一个充当按钮的图像 现在我明白 这可以通过在标准按钮上使用图像或使用称为
  • 如何在AsyncTask中举杯,提示我使用Looper

    我有 AsyncTask 在后台完成的任务 在某些时候 我需要发出一个 Toast 来表示某件事已完成 我尝试过但失败了因为Caused by java lang RuntimeException Can t create handler
  • 创建自定义 Google Now 卡片

    Google 为 Google Now 提供了各种 卡片 http www google com landing now http www google com landing now 可以创建自己的卡片吗 该系统看起来非常模块化 但我还没

随机推荐