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 metadata
*/
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 descriptive information
*/
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 descriptive information
*/
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 暗号化を使用するかどうか。現在、AES-128 暗号化はサポートされていません。
- key: 暗号化が有効な場合のキー。現在、この機能はサポートされていません。
- handler_func: オブジェクト操作のコールバック関数。
- pat_interval_frame_count: 挿入された2つのPATまたは挿入された 2 つMATテーブル間のフレーム数。
HLS ファイルを開く
/**
* @brief Open an OSS HLS file
* @param[in] Name of the bucket that stores objects in bucket_name oss
* @param[in] Name of the object in object_key oss
* @param[in] auth_func The authorization function to set access_key_id/access_key_secret
* @return:
* If NULL is returned, it indicates success. Otherwise, it indicates failure.
*/
oss_media_hls_file_t* oss_media_hls_open(char *bucket_name, char *object_key, auth_fn_t auth_func);
注意: サンプルコードは GitHubで見つけることができます。
HLS ファイルを閉じる
/**
* @brief Close the OSS HLS file
*/
int oss_media_hls_close(oss_media_hls_file_t *file);
注意:サンプルコードは GitHub で見つけることができます。
HLS ファイルを書く
/**
* @brief Write a frame of data in H.264 or AAC format to the OSS
* @param[in] frame A frame of data in H.264 or AAC format
* @param[out] file HLS file
* @return:
* If 0 is returned, it indicates the operation is successful.
* Otherwise, it indicates an error has occured
*/
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";
/* Read the H.264 file */
buf_h264 = calloc(max_size, 1);
file_h264 = fopen(h264_file_name, "r");
len_h264 = fread(buf_h264, 1, max_size, file_h264);
/* Initialize the frame struct */
frame.stream_type = st_h264;
frame.pts = 0;
frame.continuity_counter = 1;
frame.key = 1;
/* Tranverse the H.264 data and extract the data of every frame, and then write the data into the OSS */
for (i = 0; i < len_h264; i++) {
/* Determine whether the current location is the starting point of the data of the next frame, that is, the end of the current frame */
if ((buf_h264[i] & 0x0F)==0x00 && buf_h264[i+1]==0x00
&& buf_h264[i+2]==0x00 && buf_h264[i+3]==0x01)
{
cur_pos = i;
}
/* If the data of a complete frame can be obtained, call the interface to convert the data into the HLS format and write the data into the 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;
}
/* Close the object and release the resource */
fclose(file_h264);
free(buf_h264);
}
注意:
- サンプルコードは GitHub で見つけることができます。
- H.264 データに Access Unit Delimiter NAL(00 00 00 01 09 xx) がない場合、この NAL が必要です。それ以外の場合は、iPad、iPhone、Safari でオーディオやビデオを再生できません。
- H.264 フレームは、0xX0、0x00、0x00、0x01 で区切られます。 AAC フレームは 0xFF と 0x0X で区切られます。
- 現在のフレームがキーフレームの場合、frame.key を 1 に設定する必要があります。
M3U8 オブジェクトを書く
/**
* @brief Write the header data of the M3U8 object
* @param[in] max_duration The maximum duration of the TS object
* @param[in] sequence The starting number of the TS object
* @param[out] file M3U8 file
* @return:
* If 0 is returned, it indicates the operation was successful.
* Otherwise, if "-1" is returned, it indicates an error has occurred.
*/
void oss_media_hls_begin_m3u8(int32_t max_duration,
int32_t sequence,
oss_media_hls_file_t *file);
/**
* @brief Write the data of the M3U8 object
* @param[in] size Number of the M3U8 items
* @param[in] m3u8 Details of the M3u8 item
* @param[out] file M3U8 file
* @return:
* If 0 is returned, it indicates the operation is successful.
* Otherwise, if "-1" is returned, it indicates an error has occured.
*/
int oss_media_hls_write_m3u8(int size,
oss_media_hls_m3u8_info_t m3u8[],
oss_media_hls_file_t *file);
/**
* @brief Write data such as the M3U8 object terminator
* @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>";
/* Open an HLS object to write the M3U8-format data. The object name must end with ".m3u8" */
file = oss_media_hls_open(bucket_name, key, auth_func);
if (file == NULL) {
printf("open m3u8 file[%s] failed.", key);
return;
}
/* Construct the information of three TS objects */
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"));
/* Write to the M3U8 object
oss_media_hls_begin_m3u8(10, 0, file);
oss_media_hls_write_m3u8(2, m3u8, file);
oss_media_hls_end_m3u8(file);
/* Close the HLS object */
oss_media_hls_close(file);
printf("write m3u8 to oss file succeeded\n");
}
注意:
- M3U8 V3 が現在使用されています。
- 録音シナリオでは、録音終了時にターミネータを書き込むために oss_media_hls_end_m3u8 (ファイル)インターフェイスが呼び出されます。それ以外の場合、ビデオは再生できません。ライブビデオシナリオでは、このインターフェイスを呼び出すことはできません。
- サンプルコードは GitHub で見つけることができます。
- サンプルプロジェクトでエフェクトを表示できます。
- ビデオは VLC Player から、iPhone、iPad、Mac デバイスでは Safari 経由で視聴できます。