美文网首页
ijkPlayer.5 播放H264裸流

ijkPlayer.5 播放H264裸流

作者: 搁浅的三刀流zoro | 来源:发表于2019-09-27 11:20 被阅读0次

需求:websocket 接收byte[] h264裸流,传输到c层使用ijkplayer 播放

ffmpeg播放H264裸流
功能已实现,为了方便,读取本地文件做为源数据,此工程亦可播放mp4之类文件
https://github.com/Malone1023/JoyPlayer

int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);

该函数支持filename/URL,在不大改的情况下,有两种方式可以完成播裸流的工作
1.管道文件
2.AndoidIO协议/新增URLProtocol自定义

AndoidIO之前的文章已经介绍过,本文使用管道文件来完成

注释openVideo()方法如下代码,catch exception同时注释

 String scheme = mUri.getScheme();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && mSettings.getUsingMediaDataSource() && (TextUtils.isEmpty(scheme) || scheme.equalsIgnoreCase("file"))) {
                IMediaDataSource dataSource = new FileMediaDataSource(new File(mUri.toString()));
                mMediaPlayer.setDataSource(dataSource);
            }  else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                mMediaPlayer.setDataSource(mAppContext, mUri, mHeaders);
            } else {
                mMediaPlayer.setDataSource(mUri.toString());
            }

新增setDataSourceFd()方法并且在openVideo中调用,使得调用ijk中的 setDataSource(FileDescriptor fd)方法,并调用到
ijkplayer_jni.c中的static void IjkMediaPlayer_setDataSourceFd(JNIEnv *env, jobject thiz, jint fd2)方法

String fileName = "/mnt/sdcard/yy.264";
    FileDescriptor descriptor = null;
    FileOutputStream stream;
    private void setDataSourceFd(){
        try {
            stream = new FileOutputStream(fileName);
            descriptor = stream.getFD();
           //此处只是为了调用到setDataSourceFd  并不需要实际文件
            mMediaPlayer.setDataSource(descriptor);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

2.修改ijkplayer_jni.c/IjkMediaPlayer_setDataSourceFd方法

新增:

    umask(0);
    if(mkfifo(fifoName, 0664) < 0){
        if(errno == EEXIST){
            MPTRACE("file exits\n");
        }else{    
            perror("mkfifo error");
            return -1;
        }
    }
    int fd = open(fifoName, O_RDWR);
    if(fd < 0){
        MPTRACE("open fifo error\n");
        perror("open fifo error");
        return -1;
    }

修改:

retval = ijkmp_set_data_source(mp, fifoName);

3.新增接收方法

int fd;
void ffp_write_data(FFPlayer *ffp,unsigned char * data,int len){
    if(!fd){
        fd = open(fifoName, O_WRONLY);
        if(fd < 0){
            perror("ffp_joy_write_data fifo error");
            return -1;
        }
    }
   write(fd,data,len);
}

这样 ijkPlayer就可以支持播放h264裸流啦。

可能遇到的问题:
1.ffmpeg h264 avformat_open_input err code: -1094995529 网上找的时候说各种情况的,本文遇到的问题是没打开ffmpeg对h264的支持(出现此问题可以先拿ffmpeg直接播该文件,能正常播放的话说明是跟我遇到的一样)
解决办法:
do-compile-ffmpeg.sh文件中新增如下配置,并重新编译ijk的ffmpeg库(执行compile-ffmpeg.sh,同时需要编译ijk的库,替换)

FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-demuxer=h264"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-protocol=udp"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-protocol=264"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-decoder=h264"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-parser=h264"

FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-hwaccel=h264_vaapi"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-hwaccel=h264_dxva2"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-demuxer=mjpeg"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-demuxer=rtsp"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-demuxer=rtp"
FF_CFG_FLAGS="$FF_CFG_FLAGS --enable-encoder=h264"

2.mkfifo Android Permission denied
在mkfifo的时候可能会出错,原因是需要设置对应的路径要正确
本文使用的路径 /data/data/com.abc/test.fifo(在安卓手机上跑)

3.java byte[] to c unsigned char* buf

static void
IjkMediaPlayer_set_joy_receive_data(JNIEnv* env ,jobject thiz,jbyteArray data, jint jlen)
{
    jbyte* bBuffer = (*env)->GetByteArrayElements(env,data,0);
    unsigned char* buf = (unsigned char*)bBuffer;
    IjkMediaPlayer *mp  = jni_get_media_player(env, thiz);
    ijkmp_set_joy_data(mp,buf,jlen);

}

相关文章

  • ijkPlayer.5 播放H264裸流

    需求:websocket 接收byte[] h264裸流,传输到c层使用ijkplayer 播放 ffmpeg播放...

  • 音视频:调试手段

    如何调试H264裸流? 将裸流保存成文件,然后用010 editor看结构,用vlc播放如果有00 00 00 0...

  • RTSP H264/HEVC 流 Wasm 播放

    本文将介绍 RTSP H264/HEVC 裸流如何于网页前端播放。涉及 WebSocket 代理发送流数据, Wa...

  • 《Android音视频系列-7》直播推流

    这篇文章将介绍在Android平台使用RTMPDump来进行直播推流。 一、推流核心思想 推流,可以推H264裸流...

  • ios VLC 2.2.2 出现Your input can&#

    最近在用 ios VLC 2.2.2 播放h264视频流时,如果视频流服务端出了故障,VLC播放器就会出现“You...

  • H264 推流到RTMP服务器

    使用librtmp进行推流,如果进行正常的H264推流,使用VLC等播放器,可正常播放。如果需要使用flash等播...

  • Qt音视频开发8-ffmpeg保存裸流

    一、前言 最开始做的ffmpeg保存视频文件,就是直接保存的裸流数据,裸流数据一般是H264格式的数据,这种数据文...

  • IOS-FFmpeg解码

    为了简单化,这里只是从H264视频编码格式,解码为yuv420p的原始图片格式。 H264裸流格式: 这里谈谈H2...

  • rtp封包

    1 概述 经过H264编码器编码后输出的H264裸流数据,输出的形式是以nalu的格式输出的,主要分为两层,VCL...

  • Android 笔记: AAC ADTS笔记

    一、AAC 裸流。 裸流无法播放,每一帧都要加上adts 头。 其中,profile:表示使用哪个级别的AAC,如...

网友评论

      本文标题:ijkPlayer.5 播放H264裸流

      本文链接:https://www.haomeiwen.com/subject/rrvhyctx.html