社交软件中少不了视频音讯的发送,视频音讯的发送速度将直接影响到用户收发音讯的体验。

我们先来看下优化前视频音讯紧缩、上传以及发送流程:

sequenceDiagram
AppA->>AppA: 发送端进行视频紧缩
AppA->>File Server: 上传紧缩后的视频
File Server-->>AppA: 回来视频地址
AppA->>IM Server: 发送端发送视频音讯

优化 1:视频紧缩优化

优化前

先看一下优化前的视频紧缩,经过体系 AVAssetExportSession 紧缩,运用内置的分辨率进行紧缩;这么紧缩出来有一些问题,要么是视频文件有些大,要么是视频有些含糊。

AVAssetExportSession *session = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPreset960x540];
session.outputFileType = AVFileTypeMPEG4;
session.outputURL = [NSURL fileURLWithPath:localPath];
[session exportAsynchronouslyWithCompletionHandler:^{
    AVAssetExportSessionStatus status = session.status;
  if (status == AVAssetExportSessionStatusCompleted) {
        // 视频紧缩完结
        // 将紧缩后的视频途径记录在 message 中
    } else {
        // 视频紧缩失利
        // 处理失利情况
    }
}];

苹果内置参数:
苹果视频紧缩内置参数 Export Presets

优化后

修改为自定义紧缩参数,经过 AVAssetWriter 和 AVAssetReader 依照预设的视频参数和音频参数紧缩小视频

视频参数 参考值 备注
视频类型 mpeg4
视频途径 localPath
紧缩算法 H264High40 H264 兼容性较好
分辨率 384*848 参考的 WhatsApp 视频分辨率
比特 核算 videoSize.height * videoSize.width * 帧率(30) * 常数(每个像素点内的像素数据)
关键 30 主张大于 25,避免看着卡顿
音频参数 参数值
音频格局 aac
声道 单声道
采样率 44100
比特率 128000
LSAVAssetExportSession *session = [[LSAVAssetExportSession alloc] initWithAsset:asset];
session.delegate = self;
session.outputFileType = AVFileTypeMPEG4;
session.outputURL = [NSURL fileURLWithPath:localPath];
NSString *videoProfileLevel = AVVideoProfileLevelH264HighAutoLevel;
CGSize videoSize = [self getSuitableVideoSize:asset];
// bitrate: videoSize.height * videoSize.width * 帧率(30) * 常数(每个像素点内的像素数据)
NSInteger bitrate = videoSize.height * videoSize.width * 30 * 0.15;
// 视频参数设置
session.videoSettings = @{
    AVVideoCodecKey : AVVideoCodecH264,
    AVVideoWidthKey : @(videoSize.width),
    AVVideoHeightKey : @(videoSize.height),
    AVVideoCompressionPropertiesKey : @{
        ///挑选视频颜色编码格局(默认格局会支撑HDR, 导致视频在 mac 版本泛白)
        ///默以为: AVVideoYCbCrMatrix_*ITU_R_2020, 为支撑 HDR 的格局, 应当指定为 ITU*_R_*709*_2 通用配置
        AVVideoColorPrimariesKey : AVVideoColorPrimaries_ITU_R_709_2,
        AVVideoAverageBitRateKey : @(bitrate),   // 比特率
        AVVideoProfileLevelKey : videoProfileLevel, // 紧缩算法
        AVVideoMaxKeyFrameIntervalKey : @(30),     // 关键帧间隔
    },
};
// 音频参数设置
session.audioSettings = @{
    AVFormatIDKey : @(kAudioFormatMPEG4AAC),
    AVNumberOfChannelsKey : @1,
    AVSampleRateKey : @44100,
    AVEncoderBitRateKey : @128000,
};
[session exportAsynchronouslyWithCompletionHandler:^{
    AVAssetExportSessionStatus status = session.status;
  if (status == AVAssetExportSessionStatusCompleted) {
        // 视频紧缩完结
        // 将紧缩后的视频途径记录在 message 中
    } else {
        // 视频紧缩失利
        // 处理失利情况
    }
}];

优化成果

小视频音讯清晰度优化,在分辨率和 WhatsApp 相同的情况下,比其小许多。

此处直接运用官方数据

视频源文件大小在 120M 左右,经过紧缩后,大小可下降至 44M,保障清晰度的情况下,有用紧缩率为 37%左右。

优化 2:视频上传优化

优化前

刚开始是整个视频直接上传,遇到网络问题或者其他问题会导致上传流程失利,从头上传需求从 0 开始,用户体验较差。

优化后

经过将紧缩后的视频分片,并发上传,失利重试,提高上传成功率,削减上传等待时刻,极大的下降网络影响。

sequenceDiagram
AppA->>AppA: 发送端进行视频紧缩
AppA->>AppA: 视频分片
AppA->>File Server: 初始化视频分片上传恳求
File Server-->>AppA: 回来 uploadId
AppA->>File Server: 分片并发上传(最多 4 片),携带 uploadId 和 partNumber
File Server-->>AppA: 成功/失利,成功回来 ETag,失利进行重试机制
AppA->>File Server: 分片上传完毕,告诉服务进行兼并
File Server-->>AppA: 上传成功

注意事项:

  1. 每个恳求都需求 token 鉴权

  2. 恳求会偶现 502,从头恳求即可

  3. 兼并流的恳求需求依照 partNumber 的次序传 ETag

  4. 操控分片上传时的个数

优化成果

上传时刻较之前削减 60%

优化 3:视频边紧缩边上传优化

进一步优化上传时刻,在视频紧缩到 1/3 的时分,在满足分片的情况下,将该片回来上层进行分片上传,完成边紧缩边上传,变向的削减一些上传时刻。

终究优化成果

视频音讯发送时,紧缩+上传时刻较之前削减 67%。