直播技术初体验,简单实现直播不一样阶段

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
    • 命令后以下
      html

    • 查看 而后你就能够在这个目录 /usr/local/var/www/hls 看到生成一个个ts的文件,还会生成一个你的 m3u8 的文件名称.m3u8的文件
      nginx

    • 测试地址:http://localhost:8080/hls/你的m3u8的文件名称.m3u8
    • 测试方法
      一、用 safari 浏览测试
      二、也可在 Xcode 项目中用 ijkplayer框架在模拟器中测试该地址(拉流)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 打印
    github

  • 模拟器中
    bash

4、其余

    • 直播要考虑的问题不少
      • 主要是延迟:转发环节越多,延迟越大;长链接会比短链接会下降延迟
      • 网络不稳定时,断线自动重连
      • ...
    • 直播已有一些 SDK ,如暴风云直播、七牛云直播、网易云信直播 SDK、腾讯直播 SDK 等,可选性比较多,第三方框架也比较多,固然也有经过本身封装的协议进行直播的
相关文章
相关标签/搜索