最近要做视频直播类的app,之前基本没有接触过多媒体开发,在网上找了一些博客和代码看了下,慢慢入手。
先从最基本的使用开始,功能包括
* 使用surfaceView在非主线程绘制界面
* 使用surfaceView和medioVideo播放本地和网络视频
先上效果图
代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tech.myapplication">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context="com.tech.myapplication.MainActivity">
<SurfaceView
android:id="@+id/surface"
android:layout_width="match_parent"
android:layout_height="300dp" />
<Button
android:id="@+id/play"
android:text="play"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
package com.tech.myapplication;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private SurfaceView surfaceView;
private Button play;
private MediaPlayer mediaPlay;
private SurfaceHolder holder;
private int possion = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/**
* 自定义surfaceView绘图,就调用下面
*/
// setContentView(new MySurfaceView(this));
/**
* 用surfaceView播放视频
*/
setContentView(R.layout.activity_main);
initPlayView();
}
private void initPlayView() {
this.surfaceView = (SurfaceView) findViewById(R.id.surface);
this.play = (Button) findViewById(R.id.play);
this.holder = surfaceView.getHolder();
this.mediaPlay = new MediaPlayer();
//设置播放时打开屏幕
this.holder.setKeepScreenOn(true);
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
this.holder.addCallback(new MyCallback());
play.setOnClickListener(this);
}
public void play() throws IllegalArgumentException, SecurityException,
IllegalStateException, IOException {
mediaPlay.reset();
mediaPlay.setAudioStreamType(AudioManager.STREAM_MUSIC);
//本地路径视频
String path = null;
if (android.os.Environment.getExternalStorageState().
equals(Environment.MEDIA_MOUNTED)){
path = Environment.getExternalStorageDirectory().toString()+"/testfile.mp4";
}
mediaPlay.setDataSource("http://play13.68mtv.com/play13/60329.mp4");
// 把视频输出到SurfaceView上
mediaPlay.setDisplay(holder);
//不要用prepareAsync,用了也报错,ERROR(-38,0)
mediaPlay.prepare();
mediaPlay.start();
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.play:
try {
play();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
private class MyCallback implements SurfaceHolder.Callback{
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
play();
mediaPlay.seekTo(possion);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
}
@Override
protected void onPause() {
if (mediaPlay.isPlaying()) {
// 保存当前播放的位置
possion = mediaPlay.getCurrentPosition();
mediaPlay.stop();
}
super.onPause();
}
@Override
protected void onDestroy() {
if (mediaPlay.isPlaying())
mediaPlay.stop();
mediaPlay.release();
super.onDestroy();
}
/***************************************************************/
class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder holder;
private Context context;
private MyThread myThread;
public MySurfaceView(Context context) {
super(context);
this.context = context;
this.holder = this.getHolder();
this.holder.addCallback(this);
this.myThread = new MyThread(holder);
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
myThread.isRun = true;
myThread.start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
myThread.isRun = false;
}
}
class MyThread extends Thread {
public boolean isRun;
private SurfaceHolder holder;
public MyThread(SurfaceHolder holder) {
this.holder = holder;
isRun = true;
}
@Override
public void run() {
super.run();
int count = 0;
while (isRun) {
Canvas c = null;
try {
synchronized (holder) {
c = holder.lockCanvas();//锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。
c.drawColor(Color.GREEN);
Paint p = new Paint();
p.setColor(Color.WHITE);
Rect r = new Rect(100, 50, 300, 250);
c.drawRect(r, p);
p.setTextSize(40);
c.drawText("这是第" + (count++) + "秒", 100, 310, p);
Thread.sleep(1000);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (c != null) {
holder.unlockCanvasAndPost(c);//结束锁定画图,并提交改变。
}
}
}
}
}
}