直播技術初體驗,簡單實現直播不一樣階段

1、前言

  • 隨着時代的改變,人們對於內容的需求也不斷提升,從文字到圖片到音頻、視頻,可能到之後的 VR
  • 直播是一個很是燒錢的項目,須要足夠多的帶寬,足夠好的服務器,好比負載均衡,這裏還會扯到雲等等,保證大數據併發,百萬人同時訪問等等
  • 涉及到一些專業的視頻相關的知識,也須要很長時間的學習,如解碼(硬解、軟解)、編碼、轉碼,還有底層的 ffmpeg(錄製、轉換以及流化音視頻的完整解決方案)
  • 涉及到 即時通信 和 美顏處理,其中美顏涉及到 OpenGL ,以及基於 OpenGL 的圖像/視頻處理框架 GPUImage
  • 涉及到 CDN:(Content Delivery Network),即內容分發網絡,將網站的內容發佈到最接近用戶的網絡」邊緣」,使用戶能夠就近取得所需的內容,解決 Internet 網絡擁擠的情況,提升用戶訪問網站的響應速度.
  • 一個簡單的模型:主播-->直播流媒體服務器--> 多個用戶同時觀看
  • 簡單的流程:採集(流)-->編碼-->傳輸-->解碼-->播放
  • 移動端主要協議
    • RTMP 協議 Macromedia(Adobe) 公司協議
    • HTTP Live Streaming(HLS) Apple 公司協議
    • HLS流和RTMP對比:
      HLS 主要是延時比較大 ,基於 HTTP
      RTMP 主要優點在於延時低,基於 TCP

2、階段

  • 一、客戶端拿到服務器分配好的 URL 直接解碼播放直播視頻。直接客戶端拉流
  • 二、本身搭建服務器,播放的流本身控制。服務器推流,客戶端拉流
  • 三、調用客戶端攝像頭等進行錄製,客戶端推流,服務器接受流

3、各階段簡要說明

一、拿到 URL 進行解碼播放直播的視頻

  • 使用 ijkplayer ,可從網上找別人打包好的靜態庫,直接拖到工程中使用
  • 直接用 IJKFFMoviePlayerController 建立 player,設置 player 中屬性 view 的尺寸,加入到控制器的 view 上
  • 界面不播放,最好要記得結束播放
@interface ViewController ()
@property (nonatomic, strong) id<IJKMediaPlayback> player;
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.player = [[IJKFFMoviePlayerController alloc]initWithContentURL:[NSURL URLWithString:@"rtmp://live.hkstv.hk.lxdns.com/live/hks"] withOptions:nil];
    // 設置 player 中 view 屬性的frame,且加入到控制器的 view 中
    self.player.view.frame = self.view.bounds;
    [self.view addSubview:self.player.view];
    // 設置 橫屏時自動伸縮
    self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    [self.player prepareToPlay];
    [self.player play];
}
- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [self.player stop];
    self.player = nil;
}

二、本身搭建服務器,服務器推流,客戶端拉流

  • mac 環境推薦搭建 Nginx + rtmp ,可網上搜索怎麼搭建的
  • 配置 nginx.conf
    • 支持 rtmp
nginx.conf, 找到/usr/local/etc/nginx/nginx.conf 文件,

http {
    ……
}
# 在http節點下面(也就是文件的尾部)加上rtmp配置:
rtmp {
    server {
        listen 1935;
        application xxx {
            live on;
            record off;
        }
    }
}

說明:
rtmp是協議名稱
server 說明內部中是服務器相關配置
listen 監聽的端口號, rtmp協議的默認端口號是1935
application 訪問的應用路徑是 xxx
live on; 開啓實時
record off; 不記錄數據
    • 支持 hls
只是簡單的修改下配置文件 nginx.conf 便可
1.打開 /usr/local/etc/nginx/nginx.conf
2.找到 http 下的 server ,在花括號中增長
server {
        listen       8080;
        server_name  localhost;

        location / {
            root   html;
            index  index.html index.htm;
        }
       #HLS配置開始,這個配置爲了`客戶端`可以以http協議獲取HLS的拉流
        location /hls {
            # Serve HLS fragments
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root html;
            add_header Cache-Control no-cache;
        }
       #HLS配置結束
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    找到rtmp 下的  server 在花括號中增長
    rtmp {
    server {
        listen 1935;
        application xxx {
            live on;
            record off;
        }
        #增長對HLS支持開始
        #推流必須是基於H264/AAC格式
        application hls {
            live on;
            hls on;
            hls_path /usr/local/var/www/hls;
        }
      #增長對HLS支持結束
    }
}
  • 配置完 config 後
    nginx -s reload
  • ffmpeg 命令測試 rtmp
    • 命令:該命令會開啓桌面分享、音頻、視頻
ffmpeg -f avfoundation -framerate 30 -i "1:0" -f avfoundation -framerate 30 -video_size 640x480 -i "0" -c:v libx264 -preset ultrafast -filter_complex 'overlay=main_w-overlay_w-10:main_h-overlay_h-10' -acodec libmp3lame -ar 44100 -ac 1  -f flv rtmp://192.168.33.245:1935/xxx/room
    • rtmp 地址
rtmp://192.168.33.245:1935/xxx/room
    • 該 rtmp 地址中,ip地址和 xxx/room 自行根據本身的配置替換,room 暫時可隨便寫,具體怎麼分配還不是很清楚
      • 開啓後以下
      • 測試:
      • 一、就能夠在 VLC 中打開網絡 URL,輸入 rtmp 地址就能夠測試了
      • 二、也可在 Xcode 項目中用 ijkplayer框架在模擬器中測試該地址(拉流)
  • ffmpeg 命令測試 hls
    • 轉換測試
ffmpeg -loglevel verbose -re -i /Users/HOWIE-CH/Desktop/1.mp4 -vcodec libx264 -vprofile baseline -acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost:1935/hls/1
    • 命令後以下
+ 查看 而後你就能夠在這個目錄 /usr/local/var/www/hls 看到生成一個個ts的文件,還會生成一個你的 m3u8 的文件名稱.m3u8的文件

+ 測試地址:http://localhost:8080/hls/你的m3u8的文件名稱.m3u8
+ 測試方法
    一、用 safari 瀏覽測試
    二、也可在 Xcode 項目中用 ijkplayer框架在模擬器中測試該地址(拉流)

三、客戶端推流

  • 相關第三方框架:
    • GDLiveStreaming 是對開源框架 VideoCore 簡單封裝.提供視頻錄製,推送與存儲
    • https://github.com/goodow/GDLiveStreaming.git
#import "ViewController.h"
#import <GDLiveStreaming/GDLRawDataOutput.h>
#import <GPUImage/GPUImageVideoCamera.h>
#import <GPUImage/GPUImageView.h>
@interface ViewController ()
@property (nonatomic, strong) GPUImageVideoCamera *camera;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    //  1. 建立視頻攝像頭
    self.camera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset1280x720
                                                      cameraPosition:AVCaptureDevicePositionBack];
    //  2. 設置攝像頭幀率
    self.camera.frameRate = 25;
    //  3. 設置攝像頭輸出視頻的方向
    self.camera.outputImageOrientation = UIInterfaceOrientationPortraitUpsideDown;

    
    //  4. 建立用於展現視頻的GPUImageView
    GPUImageView *imageView = [[GPUImageView alloc] init];
    imageView.frame = self.view.bounds;
    [self.view addSubview:imageView];

    //  4.1 添加GPUImageView爲攝像頭的的輸出目標
    [self.camera addTarget:imageView];

    //  5. 建立原始數據輸出對象
    GDLRawDataOutput *output = [[GDLRawDataOutput alloc] initWithVideoCamera:self.camera withImageSize:CGSizeMake(720, 1280)];

    //  5.1 添加數據輸出對象爲攝像頭輸出目標
    [self.camera addTarget:output];

    

    //  6.開啓前置攝像頭, 不寫這句代碼默認開啓的是後置攝像頭
    [self.camera rotateCamera];

    //  7.開始捕獲視頻
    [self.camera startCameraCapture];

    //  8.開始上傳視頻
    [output startUploadStreamWithURL:@"rtmp://192.168.33.245:1935/zhanghao" andStreamKey:@"room"];
}
@end
  • mac 電腦(搭建 Nginx 服務器)網段和真機的網段最好是同一局域網網段下,或者用外網測試
  • 真機作推流到 mac上(搭建 Nginx 服務器),而後用 Xcode 裏模擬器當其餘客戶端拉流
  • 真機 debug 打印
    html

  • 模擬器中
    nginx

4、其餘

  • 直播要考慮的問題不少
    • 主要是延遲:轉發環節越多,延遲越大;長鏈接會比短鏈接會下降延遲
    • 網絡不穩定時,斷線自動重連
    • ...
  • 直播已有一些 SDK ,如暴風雲直播、七牛雲直播、網易雲信直播 SDK、騰訊直播 SDK 等,可選性比較多,第三方框架也比較多,固然也有經過本身封裝的協議進行直播的
相關文章
相關標籤/搜索