国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android MediaCodec將h264實(shí)時(shí)視頻流數(shù)據(jù)解碼為yuv,并轉(zhuǎn)換yuv的顏色格式為nv21

這篇具有很好參考價(jià)值的文章主要介紹了Android MediaCodec將h264實(shí)時(shí)視頻流數(shù)據(jù)解碼為yuv,并轉(zhuǎn)換yuv的顏色格式為nv21。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

初始化mediacodec

    //寬高根據(jù)攝像頭分辨率設(shè)置
    private int Width = 1280;
    private int Height = 720;
    private MediaCodec mediaCodec;
    private ByteBuffer[] inputBuffers;

    private void initMediaCodec(Surface surface) {

        try {
            Log.d(TAG, "onGetNetVideoData: ");
            //創(chuàng)建解碼器 H264的Type為  AAC
            mediaCodec = MediaCodec.createDecoderByType("video/avc");
            //創(chuàng)建配置
            MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", Width, Height);
            //設(shè)置解碼預(yù)期的幀速率【以幀/秒為單位的視頻格式的幀速率的鍵】
            mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 20);

            mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, COLOR_FormatYUV420SemiPlanar);//
//            byte[] headerSps = {0, 0, 0, 1, 103, 66, 0, 41, -115, -115, 64, 80, 30, -48, 15, 8, -124, 83, -128};
//            byte[] headerPps = {0, 0, 0, 1, 104, -54, 67, -56};
//
//            mediaFormat.setByteBuffer("csd-0", ByteBuffer.wrap(headerSps));
//            mediaFormat.setByteBuffer("csd-1", ByteBuffer.wrap(headerPps));
            //配置綁定mediaFormat和surface
            mediaCodec.configure(mediaFormat, null, null, 0);
            mediaCodec.start();
        } catch (IOException e) {
            e.printStackTrace();
            //創(chuàng)建解碼失敗
            Log.e(TAG, "創(chuàng)建解碼失敗");
        }

        inputBuffers = mediaCodec.getInputBuffers();

    }

處理數(shù)據(jù),解碼h264數(shù)據(jù)為yuv格式

這里傳入的是h264格式的實(shí)時(shí)視頻流數(shù)據(jù)。

    private void onFrame(byte[] buf, int offset, int length) {

        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
        //查詢10000毫秒后,如果dSP芯片的buffer全部被占用,返回-1;存在則大于0
        int inIndex = mediaCodec.dequeueInputBuffer(10000);
        if (inIndex >= 0) {
            //根據(jù)返回的index拿到可以用的buffer
            ByteBuffer byteBuffer = inputBuffers[inIndex];
            //清空緩存
            byteBuffer.clear();
            //開始為buffer填充數(shù)據(jù)
            byteBuffer.put(buf);
            //填充數(shù)據(jù)后通知mediacodec查詢inIndex索引的這個(gè)buffer,
            mediaCodec.queueInputBuffer(inIndex, 0, length, mCount * 20, 0);
            mCount++;
        } else {
            Log.i(TAG, "inIndex < 0");
            //等待查詢空的buffer
            return;
        }
        //mediaCodec 查詢 "mediaCodec的輸出方隊(duì)列"得到索引
        int outIndex = mediaCodec.dequeueOutputBuffer(info, 10000);
        Log.e(TAG, "解碼輸出outIndex " + outIndex);
        if (outIndex >= 0) {

            //dsp的byteBuffer無法直接使用
            ByteBuffer byteBuffer = mediaCodec.getOutputBuffer(outIndex);
            //設(shè)置偏移量
            byteBuffer.position(info.offset);
            byteBuffer.limit(info.size + info.offset);

            byte[] ba = new byte[byteBuffer.remaining()];
            byteBuffer.get(ba);
            //需要預(yù)先分配與NV12相同大小的字節(jié)數(shù)組
            byte[] yuv = new byte[ba.length];
            //不確定是什么顏色格式,挨個(gè)試的
            //convertI420ToNV21(ba, yuv, Width, Height);
            //convertYV12toNV21(ba, yuv, Width, Height);
            convertNV12toNV21(ba, yuv, Width, Height);
            NV21Data(yuv);
            //檢查所支持的顏色格式
//            MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType("video/avc");
//             for (int i = 0; i < capabilities.colorFormats.length; i++) {
//                int format = capabilities.colorFormats[i];
//
//                //華為平板:COLOR_FormatYUV420SemiPlanar、COLOR_FormatYUV420Planar
//                //魅族手機(jī):COLOR_FormatYUV420SemiPlanar
//                //rk3588s: COLOR_FormatYUV420Planar、COLOR_FormatYUV420Flexible、COLOR_FormatYUV420PackedSemiPlanar、COLOR_FormatYUV420SemiPlanar
//                switch (format) {
//                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar://(對(duì)應(yīng) I420 or YV12)
//                        Log.i("COLOR_Format_TAG", "=========COLOR_FormatYUV420Planar");
//                        byte[] convertNv21YUV420Planar = new byte[ba.length];
//                        //不確定是什么顏色格式,挨個(gè)試的
                            convertI420ToNV21(ba, convertNv21YUV420Planar, Width, Height);
                            convertYV12toNV21(ba, convertNv21YUV420Planar, Width, Height);
//                        long l1 = System.currentTimeMillis();
//                        convertNV12toNV21(ba, convertNv21YUV420Planar, Width, Height);
//                        Log.i("耗時(shí)測(cè)試", "轉(zhuǎn)為nv21的耗時(shí): " + (System.currentTimeMillis() - l1));
//                        long l2 = System.currentTimeMillis();
//                        NV21Data(convertNv21YUV420Planar);
//                        Log.i("耗時(shí)測(cè)試", "識(shí)別耗時(shí): " + (System.currentTimeMillis() - l2));
//                        continue;
//
//                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar://NV12
//                        Log.i("COLOR_Format_TAG", "=======COLOR_FormatYUV420SemiPlanar");
//                        byte[] nv21YUV420SemiPlanar = new byte[ba.length];
//                        convertNV12toNV21(ba, nv21YUV420SemiPlanar, Width, Height);
//                        NV21Data(nv21YUV420SemiPlanar);
//
//                        continue;
//                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420PackedSemiPlanar:
//                        Log.i("COLOR_Format_TAG", "=======COLOR_FormatYUV420PackedSemiPlanar");
//                        byte[] nv21YUV420PackedSemiPlanar = new byte[ba.length];
//                        convertNV12toNV21(ba, nv21YUV420PackedSemiPlanar, Width, Height);
//                        NV21Data(nv21YUV420PackedSemiPlanar);
//                        continue;
//                    case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Flexible:
//                        byte[] nv21YUV420YUV420Flexible = new byte[ba.length];
//                        convertNV12toNV21(ba, nv21YUV420YUV420Flexible, Width, Height);
//                        NV21Data(nv21YUV420YUV420Flexible);
//                        Log.i("COLOR_Format_TAG", "=======COLOR_FormatYUV420Flexible");
//                        continue;
//                    default:
//                        continue;
//
//                }
//
//            }

            //如果surface綁定了,則直接輸入到surface渲染并釋放
            mediaCodec.releaseOutputBuffer(outIndex, false);
        } else {
            Log.e(TAG, "沒有解碼成功");
        }
    }

處理獲取到的nv21顏色格式的yuv數(shù)據(jù)

    private int printImageStatus = 0;
    private void NV21Data(byte[] nv21) {
          //將nv21視頻流數(shù)據(jù)傳入YuvImage中,轉(zhuǎn)換成bitmap之后,顯示在imageview上、
          //或者保存為png圖片到本地,如果不出現(xiàn)灰色、不出現(xiàn)藍(lán)色圖像和紅色圖像顏色顛倒,
          //圖像顯示正常,則說明是標(biāo)準(zhǔn)的nv21格式視頻流數(shù)據(jù)
          YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, Width, Height, null);
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          yuvImage.compressToJpeg(new Rect(0, 0, Width, Height), 100, baos);
          byte[] data = baos.toByteArray();
          Log.i(TAG, "NV21Data-data: " + data.length);
      
          Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
  
         if (bitmap != null) {
              runOnUiThread(new Runnable() {
                  @Override
                  public void run() {
                      mIvShowImage.setImageBitmap(bitmap);
                  }
              });
              //保存bitmap為png圖片
              if (printImageStatus == 0) {
                  printImageStatus = 1;
                  try {
                      File myCaptureFile = new File(Environment.getExternalStorageDirectory(), "img.png");
                      BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
                      bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
                      bos.flush();
                      bos.close();
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }
    }

?yuv視頻數(shù)據(jù)顏色格式轉(zhuǎn)換

    public static void convertI420ToNV21(byte[] i420, byte[] nv21, int width, int height) {
        System.arraycopy(i420, 0, nv21, 0, width * height);
        int offset = width * height;
        for (int i = 0; i < width * height / 4; i++) {
            nv21[offset + 2 * i] = i420[offset + i + width * height / 4];
            nv21[offset + 2 * i + 1] = i420[offset + i];
        }
    }

    public static void convertYV12toNV21(byte[] yv12, byte[] nv21, int width, int height) {
        int size = width * height;
        int vOffset = size;
        int uOffset = size + (size / 4);

        // Copy Y channel as it is
        System.arraycopy(yv12, 0, nv21, 0, size);

        for (int i = 0; i < size / 4; i++) {
            nv21[vOffset + (i * 2)] = yv12[vOffset + i];      // V
            nv21[vOffset + (i * 2) + 1] = yv12[uOffset + i];  // U
        }
    }


    public static void convertNV12toNV21(byte[] nv12, byte[] nv21, int width, int height) {
        int size = width * height;
        int offset = size;

        // copy Y channel as it is
        System.arraycopy(nv12, 0, nv21, 0, offset);

        for (int i = 0; i < size / 4; i++) {
            nv21[offset + (i * 2) + 1] = nv12[offset + (i * 2)];       // U
            nv21[offset + (i * 2)] = nv12[offset + (i * 2) + 1];       // V
        }
    }

h264實(shí)時(shí)視頻流的數(shù)據(jù)來源

    @Override
    public void onPacketEvent(byte[] data) {


        onFrame(data, 0, data.length);
        //寫入h264視頻流到sdcard中
        //wirte2file(data, data.length);

    }

寫入h264視頻流到sdcard中

    private BufferedOutputStream BufOs = null;
    private File destfile = null;
    private FileOutputStream destfs = null;
    private String dsetfilePath = Environment.getExternalStorageDirectory() + "/" + "test.h264";

    private void wirte2file(byte[] buf, int length) {
        if (isStart) {
            if (BufOs == null) {
                destfile = new File(dsetfilePath);
                try {
                    destfs = new FileOutputStream(destfile);
                    BufOs = new BufferedOutputStream(destfs);
                    Log.d(TAG, "wirte2file-new ");
                } catch (FileNotFoundException e) {
                    // TODO: handle exception
                    Log.i("TRACK", "initerro" + e.getMessage());
                    Log.d(TAG, "wirte2file-FileNotFoundException:" + e.getMessage());
                    e.printStackTrace();
                }
            }

            try {
                BufOs.write(buf, 0, length);
                BufOs.flush();
                Log.d(TAG, "wirte2file-write");
            } catch (Exception e) {
                Log.d(TAG, "wirte2file-e: " + e.getMessage());
                // TODO: handle exception
            }

        }
    }

    private boolean isStart;

    public void onStop(View view) {
        isStart = false;
        Toast.makeText(this, "停止保存", Toast.LENGTH_SHORT).show();
    }

    public void onStart(View view) {
        isStart = true;
        Toast.makeText(this, "開始保存", Toast.LENGTH_SHORT).show();
    }

rtsp獲取h264實(shí)時(shí)視頻流數(shù)據(jù)

public class FFDemuxJava {

    static {
        System.loadLibrary("demux");
    }

    private long m_handle = 0;
    private EventCallback mEventCallback = null;

    public void init(String url) {
        m_handle = native_Init(url);
    }

    public void Start() {
        native_Start(m_handle);
    }

    public void stop() {
        native_Stop(m_handle);
    }

    public void unInit() {
        native_UnInit(m_handle);
    }

    public void addEventCallback(EventCallback callback) {
        mEventCallback = callback;
    }


    private void playerEventCallback(int msgType, float msgValue) {
        if(mEventCallback != null)
            mEventCallback.onMessageEvent(msgType, msgValue);

    }


    private void packetEventCallback(byte[]data) {
        if(mEventCallback != null)
            mEventCallback.onPacketEvent(data);

    }



    private native long native_Init(String url);

    private native void native_Start(long playerHandle);

    private native void native_Stop(long playerHandle);

    private native void native_UnInit(long playerHandle);


    public interface EventCallback {
        void onMessageEvent(int msgType, float msgValue);
        void onPacketEvent(byte []data);
    }

}
?編寫C代碼加載ffmpeg庫
#include <jni.h>
#include <string>

#include "FFBridge.h"

extern "C"
{
#include <libavutil/time.h>
#include <libavcodec/avcodec.h>
#include <libavcodec/packet.h>
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libavutil/opt.h>
};

extern "C" JNIEXPORT jstring JNICALL
Java_com_qmcy_demux_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}


extern "C" JNIEXPORT jstring JNICALL
Java_com_qmcy_demux_MainActivity_GetVersion(
        JNIEnv* env,
        jobject /* this */) {
    char strBuffer[1024 * 4] = {0};
    strcat(strBuffer, "libavcodec : ");
    strcat(strBuffer, AV_STRINGIFY(LIBAVCODEC_VERSION));
    strcat(strBuffer, "\nlibavformat : ");
    strcat(strBuffer, AV_STRINGIFY(LIBAVFORMAT_VERSION));
    strcat(strBuffer, "\nlibavutil : ");
    strcat(strBuffer, AV_STRINGIFY(LIBAVUTIL_VERSION));
    strcat(strBuffer, "\nlibavfilter : ");
    strcat(strBuffer, AV_STRINGIFY(LIBAVFILTER_VERSION));
    strcat(strBuffer, "\nlibswresample : ");
    strcat(strBuffer, AV_STRINGIFY(LIBSWRESAMPLE_VERSION));
    strcat(strBuffer, "\nlibswscale : ");
    strcat(strBuffer, AV_STRINGIFY(LIBSWSCALE_VERSION));
    strcat(strBuffer, "\navcodec_configure : \n");
    strcat(strBuffer, avcodec_configuration());
    strcat(strBuffer, "\navcodec_license : ");
    strcat(strBuffer, avcodec_license());
    //LOGCATE("GetFFmpegVersion\n%s", strBuffer);
    return env->NewStringUTF(strBuffer);
}


extern "C" JNIEXPORT jlong JNICALL Java_com_qmcy_demux_FFDemuxJava_native_1Init
        (JNIEnv *env, jobject obj, jstring jurl)
{
    const char* url = env->GetStringUTFChars(jurl, nullptr);
    FFBridge *bridge = new FFBridge();
    bridge->Init(env, obj, const_cast<char *>(url));
    env->ReleaseStringUTFChars(jurl, url);
    return reinterpret_cast<jlong>(bridge);
}

extern "C"
JNIEXPORT void JNICALL Java_com_qmcy_demux_FFDemuxJava_native_1Start
        (JNIEnv *env, jobject obj, jlong handle)
{
    if(handle != 0)
    {
        FFBridge *bridge = reinterpret_cast<FFBridge *>(handle);
        bridge->Start();
    }

}

extern "C"
JNIEXPORT void JNICALL Java_com_qmcy_demux_FFDemuxJava_native_1Stop
        (JNIEnv *env, jobject obj, jlong handle)
{
    if(handle != 0)
    {
        FFBridge *bridge = reinterpret_cast<FFBridge *>(handle);
        bridge->Stop();
    }
}


extern "C"
JNIEXPORT void JNICALL Java_com_qmcy_demux_FFDemuxJava_native_1UnInit
        (JNIEnv *env, jobject obj, jlong handle)
{
    if(handle != 0)
    {
        FFBridge *bridge = reinterpret_cast<FFBridge *>(handle);
        bridge->UnInit();
        delete bridge;
    }
}

源碼地址https://gitee.com/baipenggui/demux_demo.git文章來源地址http://www.zghlxwxcb.cn/news/detail-799351.html

到了這里,關(guān)于Android MediaCodec將h264實(shí)時(shí)視頻流數(shù)據(jù)解碼為yuv,并轉(zhuǎn)換yuv的顏色格式為nv21的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • [chatGPT] 如何通過JNI在Android上顯示實(shí)時(shí)視頻流

    [chatGPT] 如何通過JNI在Android上顯示實(shí)時(shí)視頻流

    相機(jī)拍攝的畫面通過local socket 獲取,所以C++的代碼可以輕易的獲取到每一幀視頻數(shù)據(jù),需要通過JNI 讓 Android顯示出來,方法有兩種,一種是在Android內(nèi)創(chuàng)建回調(diào)函數(shù)使用Bitmap 和ImageView 進(jìn)行賦值顯示,另一種也就是ChatGPT完成的,Android將surface 傳遞到JNI層內(nèi),C++來完成賦值和渲

    2023年04月26日
    瀏覽(19)
  • live555推送實(shí)時(shí)視頻流

    1,linux 環(huán)境: 官網(wǎng)上下載,下載地址:http://www.live555.com/liveMedia/public/ live555 版本:“2018.12.14” 參考:http://www.live555.com/liveMedia/faq.html 這個(gè)FAQ要仔細(xì)閱讀。 2,編譯 根據(jù)不同的平臺(tái)來配置,并生成對(duì)應(yīng)的Makefile 2.1 ARM平臺(tái): 修改交叉編譯工具 cp config.armlinux config.arm vi config.arm

    2023年04月08日
    瀏覽(16)
  • ??祵?shí)時(shí)監(jiān)控預(yù)覽視頻流接入web

    ??祵?shí)時(shí)監(jiān)控預(yù)覽視頻流接入web

    ? ? ? ? 我們采取的方案是后端獲取視頻流返回給前端,然后前端播放 根據(jù)官方文檔傳輸對(duì)應(yīng)的參數(shù)? 官方接口限制:為保證數(shù)據(jù)的安全性,取流URL設(shè)有有效時(shí)間,有效時(shí)間為5分鐘。 注意不同協(xié)議的限制不同,rtsp沒得限制但前端播放麻煩,web端展示的話ws比較好 ??甸_放平

    2024年04月17日
    瀏覽(26)
  • OpenCV獲取網(wǎng)絡(luò)攝像頭實(shí)時(shí)視頻流

    參考文章: [常用工具] OpenCV獲取網(wǎng)絡(luò)攝像頭實(shí)時(shí)視頻流_opencv網(wǎng)絡(luò)攝像頭 [常用工具] OpenCV獲取網(wǎng)絡(luò)攝像頭實(shí)時(shí)視頻流_opencv網(wǎng)絡(luò)攝像頭_落痕的寒假的博客-CSDN博客 在使用OpenCv處理視頻時(shí),無論是視頻文件還是攝像頭畫面,都要使用VideoCapture類來進(jìn)行每一幀圖像的處理。當(dāng)我們

    2024年02月01日
    瀏覽(101)
  • 設(shè)計(jì)一個(gè)像ESPN一樣的實(shí)時(shí)視頻流系統(tǒng)

    設(shè)計(jì)一個(gè)像ESPN一樣的實(shí)時(shí)視頻流系統(tǒng)

    功能需求 ?直播事件與流之間的最大延遲不超過1分鐘?系統(tǒng)應(yīng)能夠適應(yīng)大量用戶(異構(gòu)交付)?系統(tǒng)應(yīng)能將視頻轉(zhuǎn)換為不同的分辨率和編解碼器?系統(tǒng)應(yīng)具備容錯(cuò)性 視頻轉(zhuǎn)換和接收 由于我們正在實(shí)時(shí)直播整個(gè)事件,因此我們不能等待整個(gè)視頻結(jié)束后再開始將其轉(zhuǎn)換為不同的

    2024年02月07日
    瀏覽(14)
  • 安防監(jiān)控項(xiàng)目---mjpeg-streamer視頻圖像顯示(實(shí)時(shí)視頻流實(shí)現(xiàn))

    安防監(jiān)控項(xiàng)目---mjpeg-streamer視頻圖像顯示(實(shí)時(shí)視頻流實(shí)現(xiàn))

    書接上期,我們已經(jīng)實(shí)現(xiàn)了許多功能了,但是對(duì)于視頻流的實(shí)時(shí)上傳還未實(shí)現(xiàn),本期主要分享的就是如何具體實(shí)現(xiàn)網(wǎng)頁實(shí)時(shí)顯示攝像頭采集到的視頻,從而實(shí)現(xiàn)安防中監(jiān)控的功能,這個(gè)功能完成后呢,就只剩下一個(gè)功能需求了,那就是GPRS模塊,能夠?qū)崿F(xiàn)危險(xiǎn)報(bào)警的功能,也能

    2024年02月06日
    瀏覽(26)
  • 【精選】基于OpenCV的實(shí)時(shí)視頻流車牌識(shí)別(源碼&教程)

    【精選】基于OpenCV的實(shí)時(shí)視頻流車牌識(shí)別(源碼&教程)

    近年來,智能交通系統(tǒng)(ITS)在我國應(yīng)用日益廣泛。作為ITS重要組成部分的自動(dòng)車牌識(shí)別系統(tǒng)在交通流量檢測(cè)、交通誘導(dǎo)控制、違章車輛監(jiān)控等方面有著廣泛的應(yīng)用,是確保道路安全暢通的重要手段,也為統(tǒng)計(jì)有關(guān)資料,為管理者決策提供有效數(shù)字依據(jù)的重要途徑。由于一般的識(shí)別系

    2024年01月23日
    瀏覽(94)
  • Qt推流程序自動(dòng)生成網(wǎng)頁遠(yuǎn)程查看實(shí)時(shí)視頻流(視頻文件/視頻流/攝像頭/桌面轉(zhuǎn)成流媒體rtmp+hls+webrtc)

    Qt推流程序自動(dòng)生成網(wǎng)頁遠(yuǎn)程查看實(shí)時(shí)視頻流(視頻文件/視頻流/攝像頭/桌面轉(zhuǎn)成流媒體rtmp+hls+webrtc)

    推流程序?qū)⒁曨l流推送到流媒體服務(wù)器后,此時(shí)就等待驗(yàn)證拉流播放,一般可以選擇ffplay命令行播放或者vlc等播放器打開播放,也可以選擇網(wǎng)頁直接打開拉流地址播放,一般主流的瀏覽器都支持網(wǎng)頁直接播放hls/m3u8/webrtc類型的視頻流,而且推流的主要目的可能就是為了能夠在

    2024年02月05日
    瀏覽(104)
  • 基于OpenCv+Django的網(wǎng)絡(luò)實(shí)時(shí)視頻流傳輸(前后端分離)

    基于OpenCv+Django的網(wǎng)絡(luò)實(shí)時(shí)視頻流傳輸(前后端分離)

    秋風(fēng)閣——北溪入江流:https://focus-wind.com/ 秋風(fēng)閣——基于OpenCv+Django的網(wǎng)絡(luò)實(shí)時(shí)視頻流傳輸(前后端分離) 使用OpenCv捕獲攝像機(jī)畫面后,我們有時(shí)候需要將畫面顯示在界面上。本博客基于Django的前后端分離模式,將視頻流從后端讀取,傳送給前端顯示。 在使用Django進(jìn)行視頻

    2024年02月08日
    瀏覽(92)
  • VUE3 播放RTSP實(shí)時(shí)、回放(NVR錄像機(jī))視頻流(使用WebRTC)

    VUE3 播放RTSP實(shí)時(shí)、回放(NVR錄像機(jī))視頻流(使用WebRTC)

    1、下載webrtc-streamer,下載的最新window版本 Releases · mpromonet/webrtc-streamer · GitHub ?2、解壓下載包 ?3、webrtc-streamer.exe啟動(dòng)服務(wù) (注意:這里可以通過當(dāng)前文件夾下用cmd命令webrtc-streamer.exe -o這樣占用cpu會(huì)很少,直接雙擊exe文件會(huì)占用cpu) cmd? webrtc-streamer.exe -o 啟動(dòng)如下圖所示,

    2024年04月12日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包