GithubHelp home page GithubHelp logo

chineseboyly / live264streamer Goto Github PK

View Code? Open in Web Editor NEW

This project forked from zhaohuilzjtu/live264streamer

0.0 0.0 0.0 947 KB

A Project To Study RTSP Streamer H264 Video With Live555(H264硬编,live555服务)

C++ 97.38% C 1.11% Java 1.47% CMake 0.04%

live264streamer's Introduction

Live264Streamer

A Project To Study Stream H264 Video With Live555

Travis Travis Travis

Introduction

学习多媒体相关知识,相机/音视频编解码/网络直播RTSP等

实现功能

  • 使用RTSP共享设备屏幕录屏
  • 使用RTSP共享相机视频直播
  • 扫码播放RTSP直播

下载体验

Screenshot

Stream Push VLC Play VLC Play
screenshot screenshot screenshot

涉及知识点

  • 屏幕录像并将其硬编成H264:
  1. 操作屏幕录像需要Android5.0以上支持,录制之前会弹出动态权限申请弹框。
mProjectionManager = (MediaProjectionManager)getSystemService(Context.MEDIA_PROJECTION_SERVICE);
startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
  1. 在onActivityResult返回的resultCode和resultData可用于获取MediaProjection,使用MediaProjection和硬编码器创建的surface, 就可以创建一个VirtualDisplay,且VirtualDisplay显示内容会被源源不断送到编码器编码,直到MediaProjection.stop():
mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
Surface surface = mMediaCodec.createInputSurface();
mMediaProjection = projectionManager.getMediaProjection(resultCode, resultData);
mVirtualDisplay = mMediaProjection.createVirtualDisplay("H264VDisplay",
                    width, height, dpi,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION,
                    surface, null, null);
  • 摄像头拍摄并硬编码H264:
  1. YUV格式帧数据:
I420(YUV420P) YV12(YUV420P) NV12(YUV420SP) NV21(YUV420SP)
YYYYYYYYUUVV YYYYYYYYVVUU YYYYYYYYUVUV YYYYYYYYVUVU

摄像头采集的NV21帧数据转换成H264硬编码器输入使用的YUV420SemiPlanar。 对于转换操作,可以引入Libyuv库来操作,也可以用java方式。实际操作就是UV互换, 把VUVU转换为UVUV。(假如想让输出的图像变成黑白,只需要把U和V都写死成-128即可)

Camera.Parameters parameters = this.mCamera.getParameters();
parameters.setPreviewFormat(ImageFormat.NV21);  //摄像头配置
...
int colorFormat = MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar;
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat); //编码器配置
...
// 转换操作
private void swapNV21toI420SemiPlanar(byte[] source, int width, int height) {
    for (int i = width * height; i < source.length; i += 2) {
        byte temp = source[i];
        source[i] = source[i + 1];
        source[i + 1] = temp;
    }
}
  • 硬编码器使用
  1. Android4.1之后Android系统才统一了硬件编解码接口。 硬件编码的过程类似于我们过机场安检,安检机配套了若干装物品的塑料盒子,我们把需要处理的物品放进盒子。 安检过程不需要我们处理,只需要到出口轮询并从的盒子里拿走已处理完的物品即可。 Android系统硬件编码器也提供了若干这样的盒子,便是输入缓冲队列和输入缓冲队列,我们把要编码的数据放到 可用的输入缓冲去,再到输出缓冲区取处理好的数据即可。
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.start();
for (;;) {
    // 写入输入缓冲区
    int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
    if (inputBufferId >= 0) {
        ByteBuffer inputBuffer = codec.getInputBuffer(…);
        // fill inputBuffer with valid datacodec.queueInputBuffer(inputBufferId, …);
    }
    // 读取输出缓冲区
    int outputBufferId = codec.dequeueOutputBuffer(…);
    if (outputBufferId >= 0) {
        ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
        MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
        // bufferFormat is identical to outputFormat
        // outputBuffer is ready to be processed or rendered.codec.releaseOutputBuffer(outputBufferId, …);
    }
}
  1. Android5.0以后系统提供了异步回调模式,
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.setCallback(new MediaCodec.Callback() {
    @Override
    void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
    ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
    // fill inputBuffer with valid datacodec.queueInputBuffer(inputBufferId, …);
    }

    @Override
    void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
    ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
    MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
    // bufferFormat is equivalent to mOutputFormat
    // outputBuffer is ready to be processed or rendered.codec.releaseOutputBuffer(outputBufferId, …);
    }
});

Dependencies

Reference

About Me

Contact To Me

image

live264streamer's People

Contributors

huzongyao avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.