65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Android 上录制和播放视频

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.10/5 (20投票s)

2010年9月4日

CPOL

6分钟阅读

viewsIcon

249999

downloadIcon

13787

本文旨在阐明如何创建录制和播放视频的应用程序。文中还简要解释了相关API

版权所有 © 2010 Tata Consultancy Services Ltd. 保留所有权利

引言

早期版本的 Android 平台不支持视频录制,因此开发者无法创建任何视频录制应用程序。随着基于 Linux Kernel 2.6.27 的 SDK 1.5(Cupcake)的发布,引入了多项新功能和更新。此 Android 版本支持视频录制和播放。

Android 1.5(Cupcake)及后续版本(Donut 和 Eclair)提供了用于录制视频的 API。但是,很难找到相关、清晰且简单的文章来解释如何使用 Android API 录制视频。本文旨在阐明如何创建录制和播放视频的应用程序。文中还简要解释了相关API。

视频播放

Android 在 Android 媒体包下支持视频播放和录制。该包中的 MediaPlayer 类有助于视频播放。

在 j2me 等其他技术中创建媒体播放器更加复杂,因为需要创建自定义视图,需要处理进度滑块等。然而,Android 框架通过提供 VideoView 和 Media Controller 类,使视频播放变得容易。这种额外的抽象处理了大部分复杂性。

VideoView 控件封装了 MediaPlayer 的创建和实例化。VideoView 类可以从各种来源(例如资源或 SD 卡)加载视频。它负责从视频计算测量值,以便可以在任何布局管理器中使用,并提供各种显示选项,例如缩放和着色。

MediaController 是一个视图,它为 MediaPlayer 添加了控制,例如播放、暂停和进度滑块。它将控件与 MediaPlayer 的状态同步。

以下部分讨论了开发用于播放 SD 卡上视频文件的应用程序。

播放视频的步骤

步骤1:创建一个 VideoView 小部件

VideoView 添加到您的布局文件。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="fill_parent" android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<VideoView
        android:id="@+id/videoView"
        android:layout_width="200px"
        android:layout_height="200px"
       android:layout_x="10px"
       android:layout_y="10px" />
</LinearLayout>
步骤2:将其添加为 Activity 的内容

使用 setContentView 方法将 Activity 的内容设置为我们创建的视频布局文件。

@Override
protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          this.setContentView(R.layout.video);
          videoView = (VideoView)this.findViewById(R.id.videoView);
}
步骤3:设置视频路径或 URI

使用 setVideoURI 方法设置视频的路径,该路径包含视频的网址或 SD 卡上的位置。

videoView.setVideoURI(Uri.parse(“Web Address”));

videoView.setVideoURI(Uri.parse(“\sdcard\video.mp4”));

注意:要从网络读取文件,请将 Internet 权限添加到应用程序的 manifest 文件中。

(即,将 <uses-permission android:name="android.permission.INTERNET" /> 添加到应用程序的 manifest 文件中。)

步骤4:设置焦点

调用 VideoView 对象的 setFocus 方法以使 VideoView 对象获得焦点

videoView.setFocus();

您还可以添加 MediaController 来播放、停止、暂停和快进视频。创建一个 MediaController 类的对象,并将该对象传递给 VideoView 对象的 setMediaController 方法。

MediaController mc = new MediaController(this);
videoView.setMediaController(mc);

录制视频

本节解释了如何在 Android 上录制视频。为了录制视频,将使用 MediaRecorder 类。为了处理摄像头的显示,将使用 SurfaceViewSurfaceHolder.Callback 接口。

以下部分将阐明 MediaRecorderSurfaceViewSurfaceHolder.Callback 接口。

  1. MediaRecorder: 此类用于录制音频和视频。它有不同的方法来配置录音机。视频录像机中使用的这些方法如下所述
    • setVideoSource():这设置了用于录制的视频源(即摄像头或默认)。如果未调用此方法,则输出文件将不包含视频轨道。
    • setOutputFormat():这设置了录制期间生成的输出文件的格式。在 setAudioSource()/setVideoSource() 之后但在 prepare() 之前调用此方法。
    • setVideoEncoder:这设置了用于录制的视频编码器。如果未调用此方法,则输出文件将不包含视频轨道。在 setOutputFormat() 之后但在 prepare() 之前调用此方法。
    • setOutputFile():这设置了输出文件的路径。在 setOutputFormat() 之后但在 prepare() 之前调用此方法。
    • setPreviewDisplay():设置一个 Surface 来显示录制媒体(视频)的预览。在 prepare() 之前调用此方法,以确保设置了理想的预览显示。
    • prepare():准备录音机以开始捕获和编码数据。此方法必须在设置所需的音频和视频源、编码器、文件格式等之后,但在 start() 之前调用。
    • start():开始捕获和编码数据到使用 setOutputFile() 指定的文件。在 prepare() 之后调用此方法。

    注意:这些方法应按上述顺序调用。)

  2. SurfaceView: 这是一个自定义视图,在视图层次结构中提供了一个绘图表面。它用于需要快速更新或高帧速率的资源密集型任务,例如 3D 图形、创建游戏或实时预览相机。

    使用此视图的主要优点是它提供了一个独立的线程来更新视图,从而提供出色的用户体验。

  3. SurfaceHolder: 顾名思义,此接口持有 SurfaceView 对象。它允许开发人员控制表面大小和格式、编辑表面中的像素以及监视表面的更改。

现在我们可以使用上面解释的 API 来开发一个 VideoRecording 应用程序。我们将从开发自定义视图开始。

  • 创建 RecorderPreview 类,该类扩展了 SurfaceView 并实现了 SurfaceHolder.Callback 接口。
    class RecorderPreview extends SurfaceView implements SurfaceHolder.Callback
        {
          //Create objects for MediaRecorder and SurfaceHolder.
          MediaRecorder recorder;
          SurfaceHolder holder;
    
          //Create constructor of Preview Class. In this, get an object of
          //surfaceHolder class by calling getHolder() method. After that add
          //callback to the surfaceHolder. The callback will inform when surface is
          //created/changed/destroyed. Also set surface not to have its own buffers.
    
          public Preview(Contect context,MediaRecorder temprecorder) {
    	 super(context);
              recorder=temprecorder;
    	 holder=getHolder();
    	 holder.addCallback(this);
    	 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
           }
    
          // Implement the methods of SurfaceHolder.Callback interface
    
          // SurfaceCreated : This method gets called when surface is created.
          // In this, initialize all parameters of MediaRecorder object as explained
          // above.
    
          public void surfaceCreated(SurfaceHolder holder){
    	  try{
               	recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
    	   	recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    	   	recorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
    	    	recorder.setOutputFile("/sdcard/recordvideooutput.3gpp");
    	    	recorder.setPreviewDisplay(mHolder.getSurface());
    	   	recorder.prepare();
    	    } catch (Exception e) {
    	    	String message = e.getMessage()
          }
    }

    注意:为了允许录制视频,请将权限添加到应用程序的 manifest 文件中。即,添加 <uses-permission android:name="android.permission.RECORD_VIDEO"/>)。

    // SurfaceDestroyed : This method gets called immediately before the
    // surface is being destroyed. Stop camera preview because surface will no
    // longer exist.
    
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        if(recorder!=null)
        {
    	recorder.release();
    	recorder = null;
        }
    }
    
    //surfaceChanged : This method is called after the surface is created.
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)
    {
    }
    }
  • 实现视频录制应用程序的 onCreate 方法

    //Create objects of MediaRecorder and Preview class
    private MediaRecorder recorder;
    private Preview preview;
        // In this method, create an object of MediaRecorder class. Create an object of
        // RecorderPreview class(Customized View). Add RecorderPreview class object
        // as content of UI.
    
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        recorder = new MediaRecorder();
        preview = new RecorderPreview(this,recorder);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(preview);
    }
    
    //Create option menu which can be used for starting and stopping video recording.
    // Also implement the onOptionsItemSelected to handle the events for option menu.
    
    public boolean onCreateOptionsMenu(Menu menu)
    {
        menu.add(0, 0, 0, "StartRecording");
        menu.add(0, 1, 0, "StopRecording");
        return super.onCreateOptionsMenu(menu);
    }
    
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
            case 0:
                recorder.start();
                break;
            case 1:
    	   recorder.stop();
    	   break;
        }
        return super.onOptionsItemSelected(item);
    }

该应用程序现已准备好进行测试。视频录制仅适用于 SDK 1.5 或更高版本的手机。无法在模拟器上检查应用程序,您需要将其安装在手机上。

结论

在本文中,我们学习了如何开发用于视频录制、播放的应用程序,并概述了相关 API。本文附带了一个示例应用程序。希望它对开发应用程序的视频组件有所帮助。

相关资源

作者

Sandeep Andre

Sandeep Andre 拥有浦那大学计算机工程学士学位。他曾担任塔塔咨询服务有限公司孟买创新实验室的研究团队成员。他目前在北卡罗来纳大学夏洛特分校攻读计算机科学硕士学位。他的研究兴趣是移动计算、网络和操作系统。
联系方式:sandre@uncc.edu

Suneeta Chawla

Suneeta Chawla 拥有 DAVV 大学信息技术硕士学位。她是塔塔咨询服务有限公司孟买创新实验室的研究团队成员。她的研究兴趣是移动计算。
联系方式:suneeta.chawla@tcs.com

潘卡吉·多克

Pankaj Doke 拥有孟买大学计算机工程学士学位。他是塔塔咨询服务有限公司孟买创新实验室的研究团队负责人。他的研究兴趣是移动计算、计算机安全、模式识别、机器学习和大型系统。
联系方式:pankaj.doke@tcs.com

桑杰·金巴胡内

Sanjay Kimbahune 拥有 Amravati 大学电子工程学士学位。他是 Tata Consultancy Services Limited 孟买创新实验室的研究科学家。他的研究兴趣是移动计算和电信系统。
联系方式:sanjay.kimbahune@tcs.com

© . All rights reserved.