Android 直播http、rtmp流,使用ijkplayer

ijkplayer github地址

 

下载地址:

https://download.csdn.net/download/ink_s/13187728

 

效果

 

 

 

 

 

1.导入ijkplayer-java  mode

implementation project(path: ':ijkplayer-java')

 

2.自定义播放器

package com.ink.ijkplaytertest;

import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.inks.inkslibrary.Utils.L;

import java.io.IOException;

import tv.danmaku.ijk.media.player.IMediaPlayer;
import tv.danmaku.ijk.media.player.IjkMediaPlayer;

public class IjkplayerVideoView extends FrameLayout {


    private int specHeightSize;
    private int specWidthSize;
    //是否全屏拉伸填满,false等比例最大,不拉伸
    private boolean fillXY = false;


    public IjkplayerVideoView(@NonNull Context context) {
        super(context);
        initVideoView(context);
    }

    public IjkplayerVideoView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initVideoView(context);
    }

    public IjkplayerVideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initVideoView(context);
    }

    @SuppressLint("NewApi")
    public IjkplayerVideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initVideoView(context);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        specHeightSize = MeasureSpec.getSize(heightMeasureSpec);
        specWidthSize = MeasureSpec.getSize(widthMeasureSpec);
    }

    /**
     * 由ijkplayer提供,用于播放视频,需要给他传入一个surfaceView
     */
    private IMediaPlayer mMediaPlayer = null;

    /**
     * 视频文件地址
     */
    private String mPath = "";

    private SurfaceView surfaceView;

    // private VideoPlayerListener listener;
    private Context mContext;


    private void initVideoView(Context context) {
        mContext = context;
        //获取焦点
//        setFocusable(true);
    }


    private void setFillXY(boolean fillXY) {
        this.fillXY = fillXY;
    }

    /**
     * 设置视频地址。
     * 根据是否第一次播放视频,做不同的操作。
     *
     * @param path the path of the video.
     */
    public void setVideoPath(String path) {
        if (TextUtils.equals("", mPath)) {
            //如果是第一次播放视频,那就创建一个新的surfaceView
            mPath = path;
            createSurfaceView();
        } else {
            //否则就直接load
            mPath = path;
            load();
        }
    }

    /**
     * 新建一个surfaceview
     */
    private void createSurfaceView() {
        //生成一个新的surface view
        surfaceView = new SurfaceView(mContext);
        surfaceView.getHolder().addCallback(new LmnSurfaceCallback());
        LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT
                , LayoutParams.MATCH_PARENT, Gravity.CENTER);
        surfaceView.setLayoutParams(layoutParams);
        this.addView(surfaceView);
    }

    /**
     * surfaceView的监听器
     */
    private class LmnSurfaceCallback implements SurfaceHolder.Callback {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            //surfaceview创建成功后,加载视频
            load();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    }


    /**
     * 加载视频
     */
    private void load() {
        //每次都要重新创建IMediaPlayer
        createPlayer();
        try {
            mMediaPlayer.setDataSource(mPath);
            mMediaPlayer.setLooping(true);
            //mMediaPlayer.setVolume(0f,0f);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //给mediaPlayer设置视图
        mMediaPlayer.setDisplay(surfaceView.getHolder());

        mMediaPlayer.prepareAsync();
    }

    /**
     * 创建一个新的player
     */
    private void createPlayer() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.setDisplay(null);
            mMediaPlayer.release();
        }
        IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
        ijkMediaPlayer.native_setLogLevel(IjkMediaPlayer.IJK_LOG_DEBUG);

        // 设置播放前的探测时间 1,达到首屏秒开效果
        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "analyzeduration", 1);

        //开启硬解码
        // ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);

        mMediaPlayer = ijkMediaPlayer;

        mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);
        L.e("     mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);");

//        if (listener != null) {
//            mMediaPlayer.setOnPreparedListener(listener);
//            mMediaPlayer.setOnInfoListener(listener);
//            mMediaPlayer.setOnSeekCompleteListener(listener);
//            mMediaPlayer.setOnBufferingUpdateListener(listener);
//            mMediaPlayer.setOnErrorListener(listener);
//        }
    }


//    public void setListener(VideoPlayerListener listener) {
//        this.listener = listener;
//        if (mMediaPlayer != null) {
//            mMediaPlayer.setOnPreparedListener(listener);
//        }
//    }


    IMediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
            new IMediaPlayer.OnVideoSizeChangedListener() {
                public void onVideoSizeChanged(IMediaPlayer mp, int width, int height, int sarNum, int sarDen) {

                    if (width != 0 && height != 0) {
                        if (surfaceView != null) {
                            LayoutParams lp = (LayoutParams) surfaceView.getLayoutParams();
                            if (fillXY) {
                                lp.width = -1;
                                lp.height = -1;
                            } else {
                                float scanXY;
                                if ((specHeightSize / specWidthSize) > (height / width)) {
                                    //高剩余,以宽填满
                                    scanXY = specWidthSize / (float) width;
                                } else {
                                    scanXY = specHeightSize / (float) height;
                                }
                                lp.width = (int) (width * scanXY);
                                lp.height = (int) (height * scanXY);
                            }


                            surfaceView.setLayoutParams(lp);
                        }
                        //requestLayout();
                    }
                }
            };


    /**
     * 下面封装了控制视频的方法
     */

    public void setVolume(float v1, float v2) {
        //关闭声音
        if (mMediaPlayer != null) {
            mMediaPlayer.setVolume(v1, v2);
        }
    }

    public void start() {
        if (mMediaPlayer != null) {
            mMediaPlayer.start();
        }
    }

    public void release() {
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    public void pause() {
        if (mMediaPlayer != null) {
            mMediaPlayer.pause();
        }
    }

    public void stop() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
        }
    }


    public void reset() {
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
        }
    }


    public long getDuration() {
        if (mMediaPlayer != null) {
            return mMediaPlayer.getDuration();
        } else {
            return 0;
        }
    }


    public long getCurrentPosition() {
        if (mMediaPlayer != null) {
            return mMediaPlayer.getCurrentPosition();
        } else {
            return 0;
        }
    }


    public void seekTo(long l) {
        if (mMediaPlayer != null) {
            mMediaPlayer.seekTo(l);
        }
    }
}

 

 

使用

            videoView = findViewById(R.id.VideoView);
            videoView.setVideoPath(url);
            videoView.start();




    @Override
    protected void onDestroy() {
        super.onDestroy();

        videoView.stop();
        videoView.release();
    }

 

ijkplayer 的动态库v7a 和v8a,支持海康摄像头RTSP h264协议,源码来自最新版本ijkplayer k0.8.0 使用原DEMO即可支持RTSP mp4文件等播放,首画面500ms显示. module-lite-rtsp.sh的内容如下: #! /usr/bin/env bash #-------------------- # Standard options: export COMMON_FF_CFG_FLAGS= # export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --prefix=PREFIX" # Licensing options: export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-gpl" # export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-version3" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-nonfree" # Configuration options: # export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-static" # export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-shared" # export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-small" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-runtime-cpudetect" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-gray" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-swscale-alpha" # Program options: export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-programs" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffmpeg" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffplay" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffprobe" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-ffserver" # Documentation options: export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-doc" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-htmlpages" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-manpages" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-podpages" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-txtpages" # Component options: export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-avdevice" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-avcodec" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-avformat" export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-avutil" export COMMON_FF_CF
Android ijkplayer是一款强大的多媒体播放器库,可以用于在Android设备上播放各种音视频格式。其中,它也支持直播RTMP协议。 RTMP(Real-Time Messaging Protocol)是一种用于实时数据传输的协议,常用于音视频的传输,尤其适用于直播场景。通过使用Android ijkplayer,我们可以实现在Android设备上直播RTMP。 要使用ijkplayer进行RTMP直播,首先需要在Android项目中导入ijkplayer库,并在代码中进行相应设置。具体步骤如下: 1. 在项目的build.gradle文件中添加ijkplayer库的依赖: ```java implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8' implementation 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8' ``` 2. 在布局文件中添加一个SurfaceView来展示播放器画面: ```xml <SurfaceView android:id="@+id/surfaceView" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 3. 在代码中初始化播放器并设置RTMP源: ```java IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer(); ijkMediaPlayer.setDataSource("rtmp://your_rtmp_stream_url"); ijkMediaPlayer.setDisplay(surfaceView.getHolder()); ijkMediaPlayer.prepareAsync(); ``` 4. 监听播放器的准备完成事件,并开始播放: ```java ijkMediaPlayer.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() { @Override public void onPrepared(IMediaPlayer mp) { ijkMediaPlayer.start(); } }); ``` 这样,你就可以在Android设备上直播RTMP了。ijkplayer提供了丰富的功能和接口,可以实现音视频播放、暂停、重连以及全屏等操作。同时,它还支持自定义界面和样式,使得直播RTMP更加灵活和个性化。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值