`

下载远程视频完成后进行播放(SurfaceView)

阅读更多

1.上代码:
package irdc.ex08_15;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.webkit.URLUtil;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.TextView;

/* Activity实现SurfaceHolder.Callback */
public class PlayUrlVideo extends Activity implements SurfaceHolder.Callback
{
  private TextView mTextView01;
  private EditText mEditText01;

  /* 创建MediaPlayer对象 */
  private MediaPlayer mMediaPlayer01;

  /* 用以显示MediaPlayer的SurfaceView */
  private SurfaceView mSurfaceView01;

  /* SurfaceHolder对象 */
  private SurfaceHolder mSurfaceHolder01;

  //视频控制的几个按钮
  private ImageButton mPlay, mReset, mPause, mStop;

  /* 识别MediaPlayer是否已被释放 */
  private boolean bIsReleased = false;

  /* 识别MediaPlayer是否正处于暂停 */
  private boolean bIsPaused = false;

  /* LogCat输出TAG filter */
  private static final String TAG = "*****MediaPlayer*****";

  private String currentFilePath = "";

  //保存下载文件临时路径
  private String currentTempFilePath = "";
  private String strVideoURL = "";

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    /* 将.3gp图像文件存放URL网址 */
    strVideoURL = "http://www.dubblogs.cc:8751/Android/Test/Media/3gp/test.3gp";

    mTextView01 = (TextView) findViewById(R.id.myTextView1);
    mEditText01 = (EditText) findViewById(R.id.myEditText1);
    mEditText01.setText(strVideoURL);

    /* 绑定Layout上的SurfaceView */
    mSurfaceView01 = (SurfaceView) findViewById(R.id.mSurfaceView1);

    // 这句我还看出到底起什么作用
    getWindow().setFormat(PixelFormat.TRANSPARENT);

    /* 设置SurfaceHolder为Layout SurfaceView */
    mSurfaceHolder01 = mSurfaceView01.getHolder();
    mSurfaceHolder01.addCallback(this);

    // 影片指定其为固定比例
    mSurfaceHolder01.setFixedSize(160, 128);
    mSurfaceHolder01.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    mPlay = (ImageButton) findViewById(R.id.play);
    mReset = (ImageButton) findViewById(R.id.reset);
    mPause = (ImageButton) findViewById(R.id.pause);
    mStop = (ImageButton) findViewById(R.id.stop);

    /* 播放按钮 */
    mPlay.setOnClickListener(new ImageButton.OnClickListener()
    {
      public void onClick(View view)
      {
//判断SD卡是否存在
        if (checkSDCard())
        {
          strVideoURL = mEditText01.getText().toString();
//开始下载video
          playVideo(strVideoURL);
          mTextView01.setText(R.string.str_play);
        } else
        {
          mTextView01.setText(R.string.str_err_nosd);
        }
      }
    });

    /* 重新播放按钮 */
    mReset.setOnClickListener(new ImageButton.OnClickListener()
    {
      public void onClick(View view)
      {
        if (checkSDCard())
        {
          if (bIsReleased == false)
          {
            if (mMediaPlayer01 != null)
            {
//回到起始点开始重新播放
              mMediaPlayer01.seekTo(0);
              mTextView01.setText(R.string.str_play);
            }
          }
        } else
        {
          mTextView01.setText(R.string.str_err_nosd);
        }
      }
    });

    /* 暂停按钮 */
    mPause.setOnClickListener(new ImageButton.OnClickListener()
    {
      public void onClick(View view)
      {
        if (checkSDCard())
        {
          if (mMediaPlayer01 != null)
          {
            if (bIsReleased == false)
            {
              if (bIsPaused == false)
              {
                mMediaPlayer01.pause();
                bIsPaused = true;
                mTextView01.setText(R.string.str_pause);
              } else if (bIsPaused == true)
              {
                mMediaPlayer01.start();
                bIsPaused = false;
                mTextView01.setText(R.string.str_play);
              }
            }
          }
        } else
        {
          mTextView01.setText(R.string.str_err_nosd);
        }
      }
    });

    /* 终止按钮 */
    mStop.setOnClickListener(new ImageButton.OnClickListener()
    {
      public void onClick(View view)
      {
        if (checkSDCard())
        {
          try
          {
            if (mMediaPlayer01 != null)
            {
              if (bIsReleased == false)
              {
                mMediaPlayer01.seekTo(0);
                mMediaPlayer01.pause();
                mTextView01.setText(R.string.str_stop);
              }
            }
          } catch (Exception e)
          {
            mTextView01.setText(e.toString());
            Log.e(TAG, e.toString());
            e.printStackTrace();
          }
        } else
        {
          mTextView01.setText(R.string.str_err_nosd);
        }
      }
    });
  }

  /* 自定义下载URL影片并播放 */
  private void playVideo(final String strPath)
  {
    try
    {
      /* 若传入的strPath为现有播放的连接,则直接播放 */
      if (strPath.equals(currentFilePath) && mMediaPlayer01 != null)
      {
        mMediaPlayer01.start();
        return;
      } else if (mMediaPlayer01 != null)
      {
        mMediaPlayer01.stop();
      }

      currentFilePath = strPath;

      /* 重新构建MediaPlayer对象 */
      mMediaPlayer01 = new MediaPlayer();
      /* 设置播放音量 */
      mMediaPlayer01.setAudioStreamType(2);

      /* 设置显示于SurfaceHolder */
      mMediaPlayer01.setDisplay(mSurfaceHolder01);

      mMediaPlayer01.setOnErrorListener(new MediaPlayer.OnErrorListener()
      {
        // @Override
        public boolean onError(MediaPlayer mp, int what, int extra)
        {
          // TODO Auto-generated method stub
          Log.i(TAG, "Error on Listener, what: " + what + "extra: " + extra);
          return false;
        }
      });

      mMediaPlayer01
          .setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener()
          {
            // @Override
            public void onBufferingUpdate(MediaPlayer mp, int percent)
            {
              // TODO Auto-generated method stub
              Log.i(TAG, "Update buffer: " + Integer.toString(percent) + "%");
            }
          });

      mMediaPlayer01
          .setOnCompletionListener(new MediaPlayer.OnCompletionListener()
          {
            @Override
            public void onCompletion(MediaPlayer mp)
            {
              // TODO Auto-generated method stub
              Log.i(TAG, "mMediaPlayer01 Listener Completed");
              mTextView01.setText(R.string.str_done);
            }
          });

      mMediaPlayer01.setOnPreparedListener(new MediaPlayer.OnPreparedListener()
      {
        // @Override
        public void onPrepared(MediaPlayer mp)
        {
          // TODO Auto-generated method stub
          Log.i(TAG, "Prepared Listener");
        }
      });

      Runnable r = new Runnable()
      {
        public void run()
        {
          try
          {
            /* 在线程运行中,调用自定义函数下载 */
            setDataSource(strPath);
            /* 下载完后才会调用prepare */
            mMediaPlayer01.prepare();
            Log.i(TAG, "Duration: " + mMediaPlayer01.getDuration());
            mMediaPlayer01.start();
            bIsReleased = false;
          } catch (Exception e)
          {
            Log.e(TAG, e.getMessage(), e);
          }
        }
      };
//新开启一个线程进行视频下载(增强用户体验)
      new Thread(r).start();
    } catch (Exception e)
    {
      if (mMediaPlayer01 != null)
      {
        mMediaPlayer01.stop();
        mMediaPlayer01.release();
      }
    }
  }

  /* 自定义setDataSource,由线程启动 */
  private void setDataSource(String strPath) throws Exception
  {
//判断地址是否合法
    if (!URLUtil.isNetworkUrl(strPath))
    {
//这里理解为不是合法网址,就传递的local地址
      mMediaPlayer01.setDataSource(strPath);
    } else
    {
      if (bIsReleased == false)
      {
        URL myURL = new URL(strPath);
        URLConnection conn = myURL.openConnection();
        conn.connect();
        InputStream is = conn.getInputStream();
//这里可以通过conn.getContentLength()来识别源字节大小,便于添加下载进度条
        if (is == null)
        {
          throw new RuntimeException("stream is null");
        }
//获取文件名扩展名,创建临时文件
        File myFileTemp = File.createTempFile("hippoplayertmp", "."
            + getFileExtension(strPath));
//获取文件绝对路径
        currentTempFilePath = myFileTemp.getAbsolutePath();

        /* currentTempFilePath = /sdcard/mediaplayertmp39327.dat */
//构建一个输出流写文件
        FileOutputStream fos = new FileOutputStream(myFileTemp);
        byte buf[] = new byte[128];
        do
        {
          int numread = is.read(buf);
          if (numread <= 0)
          {
            break;
          }
          fos.write(buf, 0, numread);
        } while (true);
//下载完成进行MediaPlayer源设置
        mMediaPlayer01.setDataSource(currentTempFilePath);
        try
        {
          is.close();
        } catch (Exception ex)
        {
          Log.e(TAG, "error: " + ex.getMessage(), ex);
        }
      }
    }
  }
//获取下载文件后缀名
  private String getFileExtension(String strFileName)
  {
    File myFile = new File(strFileName);
    String strFileExtension = myFile.getName();
    strFileExtension = (strFileExtension.substring(strFileExtension
        .lastIndexOf(".") + 1)).toLowerCase();

    if (strFileExtension == "")
    {
      /* 若无法顺利取得扩展名,默认为.dat */
      strFileExtension = "dat";
    }
    return strFileExtension;
  }

  private boolean checkSDCard()
  {
    /* 判断存储卡是否存在 */
    if (android.os.Environment.getExternalStorageState().equals(
        android.os.Environment.MEDIA_MOUNTED))
    {
      return true;
    } else
    {
      return false;
    }
  }

  // @Override
  public void surfaceChanged(SurfaceHolder surfaceholder, int format, int w,
      int h)
  {
    // TODO Auto-generated method stub
    Log.i(TAG, "Surface Changed");
  }

  // @Override
  public void surfaceCreated(SurfaceHolder surfaceholder)
  {
    // TODO Auto-generated method stub
    Log.i(TAG, "Surface Changed");
  }

  // @Override
  public void surfaceDestroyed(SurfaceHolder surfaceholder)
  {
    // TODO Auto-generated method stub
    Log.i(TAG, "Surface Changed");
  }
//当程序停止后,进行MediaPlayer的资源释放操作
  @Override
  protected void onStop()
  {
    super.onStop();
    if (mMediaPlayer01 != null)
    {
      mMediaPlayer01.stop();
      mMediaPlayer01.release();
    }
    this.finish();

  }
}

2.main.xml文件内容比较简单
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:background="@drawable/white" android:orientation="vertical"
	android:layout_width="fill_parent" android:layout_height="fill_parent">
	<TextView android:id="@+id/myTextView1" android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:textColor="@drawable/blue"
		android:text="@string/hello" />
	<EditText android:id="@+id/myEditText1" android:layout_width="wrap_content"
		android:layout_height="wrap_content" android:text=""
		android:singleLine="True" />
	<SurfaceView android:id="@+id/mSurfaceView1"
		android:visibility="visible" android:layout_width="320px"
		android:layout_height="240px">
	</SurfaceView>
	<LinearLayout android:orientation="horizontal" 
		android:layout_height="wrap_content" android:layout_width="fill_parent"
		android:padding="10dip">
		<ImageButton android:id="@+id/play" android:layout_height="wrap_content"
			android:layout_width="wrap_content" android:src="@drawable/play" />
		<ImageButton android:id="@+id/pause"
			android:layout_height="wrap_content" android:layout_width="wrap_content"
			android:src="@drawable/pause" />
		<ImageButton android:id="@+id/reset"
			android:layout_height="wrap_content" android:layout_width="wrap_content"
			android:src="@drawable/reset" />
		<ImageButton android:id="@+id/stop" android:layout_height="wrap_content"
			android:layout_width="wrap_content" android:src="@drawable/stop" />
	</LinearLayout>
</LinearLayout>

3.注意配置文件权限添加
<uses-permission android:name="android.permission.INTERNET">
	</uses-permission>


部分color.xml文件颜色初始化以及strings.xml中的我这里就不附上了
分享到:
评论

相关推荐

    Android源码——远程视频监控程序源码.7z

    在Android平台上,开发一个远程视频监控程序涉及到许多关键的技术点,包括网络通信、音视频编解码、多媒体数据处理以及Android系统的API应用。这个"Android源码——远程视频监控程序源码.7z"文件很可能包含了一个...

    Android WebRTC 拉取SRS 服务端视频流播放视频

    最后,你需要创建一个VideoRenderer来显示接收到的远程视频。这可以是一个SurfaceView或TextureView,或者使用其他的渲染方式。 ```java VideoRendererGui.renderFrameOnMain(new VideoRenderer.Callbacks() { @...

    安卓直播视频播放流媒体IPCameraRTSPDLNA相关-切屏及仿小米视频滚动客户端.rar

    3. **渲染播放**:将解码后的视频帧渲染到SurfaceView或TextureView上进行播放。 4. **DLNA支持**:实现DLNA客户端,使应用能够搜索和播放DLNA服务器上的视频内容。 5. **UI设计**:创建用户界面,包括视频播放界面...

    Android代码-网络视频播放器源码.zip

    当用户点击播放时,视频数据会先下载一部分到本地缓冲区,然后在此基础上进行播放,避免因网络延迟导致的卡顿。 4. **SurfaceView**:Android中的`SurfaceView`是用于显示视频的理想选择,因为它在单独的渲染层上...

    安卓的一个视频播放器源码

    源码中可能会包含如何初始化MediaPlayer,加载视频文件,控制播放状态(播放、暂停、停止),以及处理错误和回调机制等内容。 2. **SurfaceView**:为了显示视频,通常会使用SurfaceView。这是一个专门用于显示...

    Android 简单视频播放器

    在我们的项目中,`VideoView`被用来加载和播放本地或远程视频文件。通过设置`setVideoURI()`方法,我们可以指定视频的来源,无论是手机存储中的文件还是HTTP/HTTPS等网络URL。 本地视频播放涉及Android文件系统和...

    android RTSP协议播放视频

    3. **SurfaceView**或TextureView:为了显示视频,需要一个视图来承载解码后的帧。常用的有SurfaceView和TextureView,它们提供了一个平台供MediaPlayer渲染视频。SurfaceView适合简单的播放需求,而TextureView则...

    VideoView+MediaPlayer 播放视频

    VideoView可以加载本地视频文件或远程视频流,并提供了全屏模式、控制播放进度等基本功能。VideoView内部实际上会创建一个SurfaceView来显示视频,因此它需要与播放器(如MediaPlayer)配合使用。 **MediaPlayer** ...

    Android应用设计源码-网络视频播放器源码.zip

    通过URL加载远程视频资源,MediaPlayer可以处理HTTP基本流和Progressive下载。 3. **数据解码与渲染**:MediaPlayer内部包含了硬件解码和软件解码的能力,根据设备支持情况选择合适的解码方式。解码后的数据通过...

    基于android实现的网络视频播放器程序源码.zip

    这通常涉及到在后台线程中下载部分视频,以减少因网络延迟引起的播放中断。 5. **视频解码**:Android支持多种硬件和软件解码器,源码可能涉及如何选择合适的解码器,以及处理不兼容的编码格式。 6. **UI设计**:...

    webrtc视频在线示例

    7. **渲染视图**:通过SurfaceView或TextureView显示视频流,监听onAddStream()事件,将接收到的远程流添加到视图中。 8. **错误处理和状态监听**:注册各种回调,如onIceCandidate()、onRenegotiationNeeded()等,...

    android视频 监控

    MediaPlayer适用于简单的视频播放,而MediaCodec和SurfaceView则更适用于解码和渲染复杂的视频流,尤其是实时监控时对性能有较高要求的情况。 2. **网络通信**:视频流通常是通过网络传输的,因此需要了解HTTP、...

    安卓例子视频播放器

    2. **网络请求与数据流处理**:在播放网络视频时,需要使用HTTP或HTTPS协议获取远程视频资源。这通常涉及到`HttpURLConnection`或第三方库如OkHttp进行网络请求,以及对返回的数据流进行处理。 3. **布局设计**:...

    Android sip 实现视频通话

    - 视频通话的界面设计也非常重要,需要集成`SurfaceView`或`TextureView`来显示本地和远程的视频流。 4. **多媒体处理**: - 视频采集:使用Android的`Camera`或`Camera2` API获取摄像头数据,然后将其传递给编码...

    android与电脑tcp视频通讯

    在Android与电脑之间实现TCP视频通讯是一项复杂但重要的任务,特别是在远程监控、视频会议和实时流媒体应用中。TCP(Transmission Control Protocol)是一种面向连接的、可靠的网络传输协议,能够确保数据包按照发送...

    Android源码——RTSP播放器源码.7z

    然后调用`prepareAsync`异步准备播放,等待准备完成后再调用`start`进行播放。 4. **错误处理和状态管理**:MediaPlayer具有多个状态,如IDLE、INITIALIZED、PREPARING、PREPARED、STARTED等。开发者需要正确处理...

    基于Android的流媒体播放器的设计与实现.pdf

    在播放器中,支持远程视频监控和多种本地视频文件格式的播放是关键。通过HTTP或RTSP等协议获取流媒体数据,可以实现远程视频的实时播放。对于本地视频文件,播放器需要能够识别并加载不同编码标准和容器格式(如MP4...

    Webrtc 视频demo(Android)

    接着,远程的MediaStream会被添加到本地的VideoView或者SurfaceView中进行渲染显示。 7. **错误处理和调试**: 在开发过程中,WebRTC提供了一系列的事件监听器和日志功能,用于调试和异常处理。例如,监听连接状态...

    android绘图

    首先,`SurfaceView`是Android提供的一种特殊的视图,它允许在后台线程中进行高性能的图形渲染,适用于游戏、视频播放或者如本例中的动态波形绘制等场景。与普通的View不同,SurfaceView有自己的Surface对象,它位于...

    Android 视频采集+RTSP完整代码(可用).zip

    在Android平台上进行视频采集并利用RTSP(Real Time Streaming Protocol)进行实时传输是移动应用开发中的常见需求,尤其是在开发视频监控、直播应用或者远程视频通信系统时。本资源提供了这样一个完整的实现,允许...

Global site tag (gtag.js) - Google Analytics