The OSS MEDIA C SDK client supports packing the received H.264 or AAC format data into TS or M3U8 format and then write the data to OSS. You can view the video and listen to the audio through the corresponding M3U8 address.


HLS-related basic interfaces are all located in the oss_media_hls.h. Currently the provided interfaces include:

  • 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

The functions and notes of usage of various interfaces are as follows:

  • Basic structs
     *  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: Stream type. Currently the st_h264 and st_aac types are supported.
    • frame_type: Frame type. Currently the ft_non_idr, ft_idr, ft_sei, ft_sps, ft_pps and ft_aud are supported.
    • pts: The display timestamp.
    • dts: The decoding timestamp.
    • continuity_counter: The incremental counter. The value ranges from 0 to 15, but the starting value is not necessarily 0. The values must be consecutive.
    • key: Whether or not it is the key frame.
    • pos: The starting position (inclusive) of the current frame data.
    • end: The ending position (exclusive) of the current frame data.
    • video_pid: The video PID.
    • audio_pid: The audio PID.
    • hls_delay_ms: The display latency (milliseconds).
    • encrypt: Whether to use AES-128 encryption. Currently AES-128 encryption is not supported.
    • key: The key when encryption is enabled. Currently this feature is not supported.
    • handler_func: The callback function of the object operation.
    • pat_interval_frame_count: The number of frames between every two inserted PAT or every two inserted MAT tables.
  • Open an HLS file
     *  @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);
    Note For the complete code, see GitHub.
  • Close an HLS file
     *  @brief  Close the OSS HLS file
    int oss_media_hls_close(oss_media_hls_file_t *file);
    Note For the complete code, see GitHub.
  • Write an HLS file
     *  @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 occurred.
    int oss_media_hls_write_frame(oss_media_hls_frame_t *frame, oss_media_hls_file_t *file);

    Example project:

    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 */
    • For the complete code, see GitHub.
    • If Access Unit Delimiter NALs (00 00 00 01 09 xx) is missing in the H.264 data, this NAL is required. Otherwise the audio or video cannot be played on iPad, iPhone, or Safari.
    • H.264 frames are separated through 0xX0, 0x00, 0x00, and 0x01. AAC frames are separated through 0xFF and 0x0X.
    • When the current frame is a key frame, frame. The key needs to be set to 1.
  • Write an M3U8 object
     *  @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 is successful.
     *      Otherwise, if "-1" is returned, it indicates an error has occured.
    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);

    Example project:

    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);
        /* 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);
        /* Close the HLS object */
        printf("write m3u8 to oss file succeeded\n");
    • M3U8 V3 is currently used.
    • In a recording scenario, the oss_media_hls_end_m3u8(file) interface is called at the end of the recording to write a terminator. Otherwise the video cannot be played. In a live video scenario, this interface cannot be called.
    • For the complete example code, see GitHub.
    • You can view the effect in the example project.
    • You can watch the video through VLC Player, and through Safari directly on iPhone, iPad, and Mac devices.