Android http格式视频播放实现

一、使用Android自带的MediaPlay(这种不支持http)

        1. 布局文件 activity_video_test.xml 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <SurfaceView
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/surfaceView"
        tools:ignore="MissingConstraints" />

</androidx.constraintlayout.widget.ConstraintLayout>

      2. Activity中具体实现,这是用kotlin实现的


import android.animation.ObjectAnimator;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.loyalquality.smartfirefighting.R;

/**
 * rtsp流是可以支持的,http不支持
 */
public class VideoTest2Activity extends AppCompatActivity
{
    private MediaPlayer mediaPlayer;
    private SurfaceView surfaceView;
    private ImageView img;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_video_test2);
        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
//        img =  findViewById(R.id.iv_img);
        surfaceView.setZOrderOnTop(true);
        surfaceView.getHolder().setFormat(Color.TRANSPARENT);

        initView();
    }

    //图片渐变消失
    public void animationView() {
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(img, "alpha", 1f, 0f);
        objectAnimator.setDuration(2000);
        objectAnimator.start();
    }

    private void initView() {
        mediaPlayer = new MediaPlayer();
        //获取SurfaceHolder 可以通过该接口来操作SurfaceView中的Surface
        SurfaceHolder surfaceHolder = surfaceView.getHolder();
        //设置Meiaplayer的准备监听
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mp) {
                //准备完成后播放
                mediaPlayer.start();
            }
        });

        surfaceHolder.addCallback(new SurfaceHolder.Callback() {
            //当SurfaceView中Surface创建时回掉
            //该方法表示Surface已经创建完成,可以在该方法中进行绘图操作
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                mediaPlayer.reset();
                try {
                    //设置视屏文件图像的显示参数
                    mediaPlayer.setDisplay(holder);

                    // 本地视频文件
//                    String videoUrl1 = "android.resource://" + getPackageName() + "/" + R.raw.handwrite_tutorial_animation;
                    Uri uri = Uri.parse("rtsp://*****@***/h264/ch1/main/av_stream");
//                    String uri = "http://********?port=1980&app=myapp&stream=video0";


                    //file.getAbsolutePath()本地视频
                    //uri 网络视频
                    mediaPlayer.setDataSource(VideoTest2Activity.this,uri);
//                    mediaPlayer.setDataSource(uri);
                    //获取第一帧图片
//                    MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//                    retriever.setDataSource(VideoTest2Activity.this,uri);
//                    Bitmap bitmap = retriever.getFrameAtTime(1+1L,MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
                    img.setImageBitmap(bitmap);
//                    animationView();
//                    retriever.release();


//                    mediaPlayer.setOnPreparedListener(mediaPlayer -> {
//                        mediaPlayer.setOnInfoListener((mp, what, extra) -> {
//                            if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
//                                surfaceView.setBackgroundColor(Color.TRANSPARENT);
//                            return true;
//                        });
//                    });
                    //prepare();表示准备工作同步进行,(准备工作在UI线程中进行)
                    //当播放网络视频时,如果网络不要 会报ARN 所以不采用该方法
                    //mediaPlayer.prepare();
                    //异步准备 准备工作在子线程中进行 当播放网络视频时候一般采用此方法
                    mediaPlayer.prepareAsync();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            //当SurfaceView的大小发生改变时候触发该方法
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }
            //Surface销毁时回掉
            //当Surface销毁时候,同时把MediaPlayer也销毁
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if (mediaPlayer!=null) {
                    mediaPlayer.stop();
                    //释放资源
                    mediaPlayer.release();
                }
            }
        });
        //设置 surfaceView点击监听
        surfaceView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        if (mediaPlayer.isPlaying()) {
                            mediaPlayer.pause();
                        } else {
                            mediaPlayer.start();
                        }
                        break;
                }
                //返回True代表事件已经处理了
                return true;
            }
        });
    }


    @Override
    protected void onResume() {
        super.onResume();
        initView();
    }

}

二、使用webview+H5来实现,http格式视频播放

         1. 用H5写的视频播放页面,video.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flv视频流播放</title>
    <style>
        html,
        body {
            position: relative;
            width: 100%;
            height: 100vh;
            overflow: hidden;
            margin: 0 auto;
            /* text-align: center; */
        }
        .video{
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            object-fit:fill;
        }
          video::-webkit-media-controls-fullscreen-button {
              display: none;
          }
          video::-webkit-media-controls-play-button {
              display: none;
          }
          video::-webkit-media-controls-timeline {
              display: none;
          }
          video::-webkit-media-controls-current-time-display{
              display: none;
          }
          video::-webkit-media-controls-time-remaining-display {
              display: none;
          }
          video::-webkit-media-controls-mute-button {
              display: none;
          }
        video::-webkit-media-controls-toggle-closed-captions-button {
            display: none;
        }
          video::-webkit-media-controls-volume-slider {
              display: none;
          }
          video::-webkit-media-controls-enclosure{
              display: none;
          }
    </style>
</head>
<body>
<!-- 会自动播放 -->
<video id="video"
       class="video"
       poster="video_bg.png"
       autoplay
       controlsList="nodownload nofullscreen noremoteplayback noplaybackrate disablePictureInPicture"
       muted></video>
<!-- 需手动播放 controls这个属性会显示播放键-->
<!--<video id="video"-->
<!--       class="video"-->
<!--       poster="bg_daily.png"-->
<!--       controlsList="nodownload nofullscreen noremoteplayback noplaybackrate"-->
<!--       controls-->
<!--       muted></video>-->
 <script id="flvjs" src="flv.js"></script>
<!--<script id="flvjs" src="http://bilibili.github.io/flv.js/dist/flv.js"></script>-->
<script>
    function initPlayer(path) {
        if (flvjs.isSupported()) {
                var flvPlayer = flvjs.createPlayer({
                           enableWorker: true,
                           enableStashBuffer: false,
                           stashInitialSize: 128,
                           type: "flv", // => 媒体类型 flv 或 mp4
                           isLive: true, // => 是否为直播流
                           hasAudio: false, // => 是否开启声音
                           url: path
                   });
                flvPlayer.attachMediaElement(video);
                flvPlayer.load();
            }
    }
</script>

</body>

</html>

        2. 布局文件 activity_video_text.xml, 其中X5WebViewSampl是自己重新的webview

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <com.test.widget.x5web.X5WebViewSample
        android:id="@+id/web_storage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</LinearLayout>

        3. activity的具体实现


import android.os.Build;
import android.os.Handler;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebSettings;
import android.widget.Toast;

import com.loyalquality.R;
import com.loyalquality.widget.x5web.BaseX5WebActivity;
import com.loyalquality.widget.x5web.X5WebViewSample;

public class CampVideoActivity extends BaseX5WebActivity
{
    public static String VIDEO_URL = "videoUrl";
    private X5WebViewSample webStorage;
    String path = "";
    private Handler mHandler = new Handler();

    @Override
    protected void initView() {
        path = getIntent().getStringExtra(VIDEO_URL);
        setContentView(R.layout.activity_daily_camp_video);
        webStorage = findViewById(R.id.wv_video);
        initWebStorage();
        webStorage.loadUrl("file:///android_asset/videoA.html");
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        goJsInitPlayer();
                    }
                });
            }
        }, 2000);
        // 设置响应JS的Alert()函数
//        webStorage.setWebChromeClient(new WebChromeClient() {
//            @Override
//            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
//                AlertDialog.Builder b = new AlertDialog.Builder(CampVideoTestActivity.this);
//                b.setTitle("Alert");
//                b.setMessage(message);
//                b.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
//                    @Override
//                    public void onClick(DialogInterface dialog, int which) {
//                        result.confirm();
//                    }
//                });
//                b.setCancelable(false);
//                b.create().show();
//                return true;
//            }
//        });
        findViewById(R.id.iv_back).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    private void initWebStorage()
    {
        //声明WebSettings子类
        WebSettings webSettings = webStorage.getSettings();

        //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
        webSettings.setJavaScriptEnabled(true);
        // 设置允许js弹框
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);

        //设置自适应屏幕,两者合用
        webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
        webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小

        //缩放操作
        webSettings.setSupportZoom(false); //支持缩放,默认为true。是下面那个的前提。
//        webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
//        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

        //其他细节操作
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //关闭webview中缓存
//        webSettings.setAllowFileAccess(true); //设置可以访问文件
//        webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
        webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式
    }

    @Override
    protected X5WebViewSample getmX5WebView() {
        return webStorage;
    }

    @Override
    protected void start() {
    }

    private void goJsInitPlayer(){
        if(path.isEmpty()){
            Toast.makeText(this,"videoUrl is null",Toast.LENGTH_SHORT).show();
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            webStorage.evaluateJavascript("javascript:initPlayer('"+path+"')", new ValueCallback<String>() {
                @Override
                public void onReceiveValue(String value) {
                    // 此处为JS返回的结果
                }
            });
        } else {
            webStorage.loadUrl("javascript:initPlayer('"+path+"')");
        }
    }

    @Override
    protected void onPause() {
        if(null != webStorage) {
            webStorage.onPause();
        }
        super.onPause();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值