HLS基礎接口__Media-C-SDK_SDK 參考_對象存儲 OSS-阿裏雲
OSS MEDIA C SDK 客戶端部分支持將接收到的H.264、AAC格式封裝為TS、M3U8格式,然後寫到OSS上,用戶通過對應的m3u8地址就可以欣賞視頻音頻了。
接口
HLS相關基礎接口都位於oss_media_hls.h中,目前提供的接口有:
- oss_media_hls_open
- oss_media_hls_write_frame
- oss_media_hls_begin_m3u8
- oss_media_hls_write_m3u8
- oss_media_hls_end_m3u8
- oss_media_hls_flush
- oss_media_hls_close
下麵詳細介紹各個接口的功能和注意事項
基礎結構體介紹
/**
* OSS MEDIA HLS FRAME的元數據
*/
typedef struct oss_media_hls_frame_s {
stream_type_t stream_type;
frame_type_t frame_type;
uint64_t pts;
uint64_t dts;
uint32_t continuity_counter;
uint8_t key:1;
uint8_t *pos;
uint8_t *end;
} oss_media_hls_frame_t;
/**
* OSS MEDIA HLS的描述信息
*/
typedef struct oss_media_hls_options_s {
uint16_t video_pid;
uint16_t audio_pid;
uint32_t hls_delay_ms;
uint8_t encrypt:1;
char key[OSS_MEDIA_HLS_ENCRYPT_KEY_SIZE];
file_handler_fn_t handler_func;
uint16_t pat_interval_frame_count;
} oss_media_hls_options_t;
/**
* OSS MEDIA HLS FILE的描述信息
*/
typedef struct oss_media_hls_file_s {
oss_media_file_t *file;
oss_media_hls_buf_t *buffer;
oss_media_hls_options_t options;
int64_t frame_count;
} oss_media_hls_file_t;
注:
- stream_type,流類型, 目前支持st_h264和st_aac兩種
- frame_type,幀類型,目前支持ft_non_idr,ft_idr,ft_sei,ft_sps,ft_pps,ft_aud等
- pts,顯示時間戳
- dts,解碼時間戳
- continuity_counter,遞增計數器,從0-15,起始值不一定取0,但必須是連續的
- key,是否是關鍵幀
- pos,當前幀數據的起始位置(含)
- end,當前幀數據的結束位置(不含)
- video_pid,視頻的pid
- audio_pid,音頻的pid
- hls_delay_ms,顯示延遲毫秒數
- encrypt,是否使用AES-128加密,目前暫不支持
- key,使用加密時的秘鑰,目前暫不支持
- handler_func,文件操作回調函數
- pat_interval_frame_count,隔多少幀插入一個pat,mpt表
打開HLS文件
/**
* @brief 打開一個OSS HLS文件
* @param[in] bucket_name oss上存儲文件的存儲空間名稱
* @param[in] object_key oss上的文件名稱
* @param[in] auth_func 授權函數,設置access_key_id/access_key_secret等
* @return:
* 返回非NULL時成功,否則失敗
*/
oss_media_hls_file_t* oss_media_hls_open(char *bucket_name, char *object_key, auth_fn_t auth_func);
注:
- 示例代碼參考:GitHub
關閉HLS文件
/**
* @brief 關閉OSS HLS文件
*/
int oss_media_hls_close(oss_media_hls_file_t *file);
注:
- 示例代碼參考:GitHub
寫HLS文件
/**
* @brief 寫H.264或者AAC的一幀數據到oss上
* @param[in] frame h.264或者aac格式的一幀數據
* @param[out] file hls file
* @return:
* 返回0時表示成功
* 否則, 表示出現了錯誤
*/
int oss_media_hls_write_frame(oss_media_hls_frame_t *frame, oss_media_hls_file_t *file);
示例程序:
static void write_frame(oss_media_hls_file_t *file) {
oss_media_hls_frame_t frame;
FILE *file_h264;
uint8_t *buf_h264;
int len_h264, i;
int cur_pos = -1;
int last_pos = -1;
int video_frame_rate = 30;
int max_size = 10 * 1024 * 1024;
char *h264_file_name = "/path/to/example.h264";
/* 讀取H.264文件 */
buf_h264 = calloc(max_size, 1);
file_h264 = fopen(h264_file_name, "r");
len_h264 = fread(buf_h264, 1, max_size, file_h264);
/* 初始化frame結構體 */
frame.stream_type = st_h264;
frame.pts = 0;
frame.continuity_counter = 1;
frame.key = 1;
/* 遍曆H.264的數據,抽取出每幀數據,然後寫入oss */
for (i = 0; i < len_h264; i++) {
/* 判斷當前位置是否下一幀數據的開頭,也就是當前幀的結尾 */
if ((buf_h264[i] & 0x0F)==0x00 && buf_h264[i+1]==0x00
&& buf_h264[i+2]==0x00 && buf_h264[i+3]==0x01)
{
cur_pos = i;
}
/* 如果獲取到完整的一幀數據,就調用接口轉為HLS格式後寫入OSS */
if (last_pos != -1 && cur_pos > last_pos) {
frame.pts += 90000 / video_frame_rate;
frame.dts = frame.pts;
frame.pos = buf_h264 + last_pos;
frame.end = buf_h264 + cur_pos;
oss_media_hls_write_frame(&frame, file);
}
last_pos = cur_pos;
}
/* 關閉文件,釋放資源 */
fclose(file_h264);
free(buf_h264);
}
注:
- 示例代碼參考:GitHub
- 如果H.264的數據中缺少Access Unit Delimiter NALs(00 00 00 01 09 xx),需要添加這個NAL,否則無法在ipad,iphone,safari上播放
- H.264的幀是通過0xX0,0x00,0x00,0x01分隔的;AAC的幀是通過0xFF,0x0X分隔的;
- 當前幀為關鍵幀時,frame.key需要設置為1
寫M3U8文件
/**
* @brief 寫M3U8文件的頭部數據
* @param[in] max_duration TS文件最長持續時間
* @param[in] sequence TS文件起始編號
* @param[out] file m3u8 file
* @return:
* 返回0時表示成功
* 否則, 返回-1時表示出現了錯誤
*/
void oss_media_hls_begin_m3u8(int32_t max_duration,
int32_t sequence,
oss_media_hls_file_t *file);
/**
* @brief 寫M3U8文件數據
* @param[in] size m3u8 item個數
* @param[in] m3u8 m3u8 item的詳細數據
* @param[out] file m3u8 file
* @return:
* 返回0時表示成功
* 否則, 返回-1時表示出現了錯誤
*/
int oss_media_hls_write_m3u8(int size,
oss_media_hls_m3u8_info_t m3u8[],
oss_media_hls_file_t *file);
/**
* @brief 寫M3U8文件的結束符等數據
* @param[out] file m3u8 file
*/
void oss_media_hls_end_m3u8(oss_media_hls_file_t *file);
示例程序:
static void write_m3u8() {
char *bucket_name;
char *key;
oss_media_hls_file_t *file;
bucket_name = "<your bucket name>";
key = "<your m3u8 file name>";
/* 打開一個HLS文件用來寫M3U8格式的數據,文件名必須以.m3u8結尾 */
file = oss_media_hls_open(bucket_name, key, auth_func);
if (file == NULL) {
printf("open m3u8 file[%s] failed.", key);
return;
}
/* 構造3個ts格式文件的信息 */
oss_media_hls_m3u8_info_t m3u8[3];
m3u8[0].duration = 9;
memcpy(m3u8[0].url, "video-0.ts", strlen("video-0.ts"));
m3u8[1].duration = 10;
memcpy(m3u8[1].url, "video-1.ts", strlen("video-1.ts"));
/* 寫入M3U8文件
oss_media_hls_begin_m3u8(10, 0, file);
oss_media_hls_write_m3u8(2, m3u8, file);
oss_media_hls_end_m3u8(file);
/* 關閉HLS文件 */
oss_media_hls_close(file);
printf("write m3u8 to oss file succeededn");
}
注:
最後更新:2016-11-23 16:04:11
上一篇:
服務端__Media-C-SDK_SDK 參考_對象存儲 OSS-阿裏雲
下一篇:
HLS封裝接口__Media-C-SDK_SDK 參考_對象存儲 OSS-阿裏雲
版本更新__產品簡介_推薦引擎-阿裏雲
UploadPart__關於MultipartUpload的操作_API 參考_對象存儲 OSS-阿裏雲
智能客服__阿裏雲ET介紹-阿裏雲
添加刪除用戶__快速開始_大數據計算服務-阿裏雲
修改路徑緩存策略__配置操作接口_API 手冊_CDN-阿裏雲
ListUsersForGroup__組管理接口_RAM API文檔_訪問控製-阿裏雲
Spark + ONS__Spark_開發人員指南_E-MapReduce-阿裏雲
修改實例SSL鏈路__實例管理_API 參考_雲數據庫 RDS 版-阿裏雲
角色創建及授權__快速開始_大數據計算服務-阿裏雲
商品發布說明__管理後台_服務商_雲市場-阿裏雲
相關內容
常見錯誤說明__附錄_大數據計算服務-阿裏雲
發送短信接口__API使用手冊_短信服務-阿裏雲
接口文檔__Android_安全組件教程_移動安全-阿裏雲
運營商錯誤碼(聯通)__常見問題_短信服務-阿裏雲
設置短信模板__使用手冊_短信服務-阿裏雲
OSS 權限問題及排查__常見錯誤及排除_最佳實踐_對象存儲 OSS-阿裏雲
消息通知__操作指南_批量計算-阿裏雲
設備端快速接入(MQTT)__快速開始_阿裏雲物聯網套件-阿裏雲
查詢API調用流量數據__API管理相關接口_API_API 網關-阿裏雲
使用STS訪問__JavaScript-SDK_SDK 參考_對象存儲 OSS-阿裏雲