1小時學會:最簡單的iOS直播推流(十)librtmp使用介紹

最簡單的iOS 推流代碼,視頻捕獲,軟編碼(faac,x264),硬編碼(aac,h264),美顏,flv編碼,rtmp協議,陸續更新代碼解析,你想學的知識這裏都有,願意懂直播技術的同窗快來看!!git

源代碼:https://github.com/hardman/AWLivegithub

rtmp(通常大寫,小寫會被認爲英文很差或不專業,iOS開發者對這一點更爲敏感)協議是Adobe公司爲Flash視頻的實時傳輸開發的一個開放協議。bash

本文不探究rtmp協議的原理,只是從代碼角度來看,客戶端如何使用librtmp完成推流功能。架構

#librtmp 項目內使用的librtmp是使用rtmpdump編譯的。若是遇到代碼上的疑問能夠經過閱讀rtmpdump的源碼尋找答案。函數

#代碼解析 ##外部接口 rtmp相關代碼在aw_rtmp.c和aw_rtmp.h中。 對外接口包含一個context和3個函數:post

//aw_rtmp_context是一個context,用於存儲一些外部傳入及內部共享的變量。
//寫成context統一管理,不然就要寫不少全局變量了。
typedef struct aw_rtmp_context{
    //rtmp url
    char rtmp_url[256];
    //librtmp 中的結構體,做爲RTMP鏈接上下文
    RTMP *rtmp;
    
    ...
    ...

    //外部狀態檢測
    //狀態變化回調,注意,不要在狀態回調中作釋放aw_rtmp_context的操做。
    //若是非要釋放,請延遲一幀。
    aw_rtmp_state_changed_cb state_changed_cb;
    //當前狀態
    aw_rtmp_state rtmp_state;
} aw_rtmp_context;

//打開rtmp
extern int aw_rtmp_open(aw_rtmp_context *ctx);

//寫入數據
extern int aw_rtmp_write(aw_rtmp_context *ctx, const char *buf, int size);

//關閉rtmp
extern int aw_rtmp_close(aw_rtmp_context *ctx);
複製代碼

3個主要函數分別是:打開,寫入數據,關閉。 除此以外,對於外部調用者來講,最重要的是要監聽rtmp鏈接的各類狀態來調整上層邏輯。 而狀態回調就在 aw_rtmp_context中。ui

項目中,初始化 & 關閉rtmp的代碼在 aw_streamer.c 中編碼

//初始化rtmp鏈接
static int8_t aw_steamer_open_rtmp_context(){
    //建立context 傳入rtmpurl及狀態回調
    if (!s_rtmp_ctx) {
        s_rtmp_ctx = alloc_aw_rtmp_context(s_rtmp_url, aw_streamer_rtmp_state_changed_callback);
    }
    //open
    return aw_rtmp_open(s_rtmp_ctx);
}

//關閉rtmp鏈接
static void aw_streamer_close_rtmp_context(){
    if (s_rtmp_ctx) {
        aw_rtmp_close(s_rtmp_ctx);
    }
    aw_log("[d] closed rtmp context");
}
複製代碼

發送數據的代碼在aw_streamer.c中:url

static void aw_streamer_send_flv_tag_to_rtmp(aw_flv_common_tag *common_tag){
    ... ...

    aw_rtmp_write(s_rtmp_ctx, (const char *)s_output_buf->data, s_output_buf->size);

    ... ...
}
複製代碼

##打開rtmpspa

//打開rtmp,都是固定套路。
int aw_rtmp_open(aw_rtmp_context *ctx){
    ...
    ...
    //初始化
    ctx->rtmp = RTMP_Alloc();
    RTMP_Init(ctx->rtmp);
    //鏈接超時
    ctx->rtmp->Link.timeout = 1;
    //設置url
    if (!RTMP_SetupURL(ctx->rtmp, ctx->rtmp_url)) {
        AWLog("[error ] aw rtmp setup url = %s\n", ctx->rtmp_url);
        recode = -2;
        goto FAILED;
    }
    
    //可寫
    RTMP_EnableWrite(ctx->rtmp);
    
    //buffer長度
    RTMP_SetBufferMS(ctx->rtmp, 0);
    
    //開始鏈接
    if (!RTMP_Connect(ctx->rtmp, NULL)) {
        recode = -3;
        goto FAILED;
    }
    
    //鏈接
    if (!RTMP_ConnectStream(ctx->rtmp, 0)) {
        recode = -4;
        goto FAILED;
    }
    return 1;
FAILED:
    //若中間環節出錯,斷開鏈接
    aw_rtmp_close(ctx);
    return !recode;
}
複製代碼

##rtmp寫入(發送)數據

int aw_rtmp_write(aw_rtmp_context *ctx, const char *buf, int size){
    ... ...
    //RTMP_Write內部有時會排出SIGPIPE信號,在這裏處理一下
    signal(SIGPIPE, SIG_IGN);
    int write_ret = RTMP_Write(ctx->rtmp, buf, size);
    ... ...
    return write_ret;
}
複製代碼

rtmp關閉

int aw_rtmp_close(aw_rtmp_context *ctx){
    ... ...
    //主要這兩句
    RTMP_Close(ctx->rtmp);
    RTMP_Free(ctx->rtmp);
    ... ...
    return 1;
}
複製代碼

librtmp庫使用方法介紹完畢。

文章列表

  1. 1小時學會:最簡單的iOS直播推流(一)項目介紹
  2. 1小時學會:最簡單的iOS直播推流(二)代碼架構概述
  3. 1小時學會:最簡單的iOS直播推流(三)使用系統接口捕獲音視頻
  4. 1小時學會:最簡單的iOS直播推流(四)如何使用GPUImage,如何美顏
  5. 1小時學會:最簡單的iOS直播推流(五)yuv、pcm數據的介紹和獲取
  6. 1小時學會:最簡單的iOS直播推流(六)h26四、aac、flv介紹
  7. 1小時學會:最簡單的iOS直播推流(七)h264/aac 硬編碼
  8. 1小時學會:最簡單的iOS直播推流(八)h264/aac 軟編碼
  9. 1小時學會:最簡單的iOS直播推流(九)flv 編碼與音視頻時間戳同步
  10. 1小時學會:最簡單的iOS直播推流(十)librtmp使用介紹
  11. 1小時學會:最簡單的iOS直播推流(十一)sps&pps和AudioSpecificConfig介紹(完結)
相關文章
相關標籤/搜索