edit-icon download-icon

HLS basic interfaces

Last Updated: Dec 22, 2017

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.

Interface

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

  1. /**
  2. * OSS MEDIA HLS FRAME metadata
  3. */
  4. typedef struct oss_media_hls_frame_s {
  5. stream_type_t stream_type;
  6. frame_type_t frame_type;
  7. uint64_t pts;
  8. uint64_t dts;
  9. uint32_t continuity_counter;
  10. uint8_t key:1;
  11. uint8_t *pos;
  12. uint8_t *end;
  13. } oss_media_hls_frame_t;
  14. /**
  15. * OSS MEDIA HLS descriptive information
  16. */
  17. typedef struct oss_media_hls_options_s {
  18. uint16_t video_pid;
  19. uint16_t audio_pid;
  20. uint32_t hls_delay_ms;
  21. uint8_t encrypt:1;
  22. char key[OSS_MEDIA_HLS_ENCRYPT_KEY_SIZE];
  23. file_handler_fn_t handler_func;
  24. uint16_t pat_interval_frame_count;
  25. } oss_media_hls_options_t;
  26. /**
  27. * OSS MEDIA HLS FILE descriptive information
  28. */
  29. typedef struct oss_media_hls_file_s {
  30. oss_media_file_t *file;
  31. oss_media_hls_buf_t *buffer;
  32. oss_media_hls_options_t options;
  33. int64_t frame_count;
  34. } 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

  1. /**
  2. * @brief Open an OSS HLS file
  3. * @param[in] Name of the bucket that stores objects in bucket_name oss
  4. * @param[in] Name of the object in object_key oss
  5. * @param[in] auth_func The authorization function to set access_key_id/access_key_secret
  6. * @return:
  7. * If NULL is returned, it indicates success. Otherwise, it indicates failure.
  8. */
  9. 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

  1. /**
  2. * @brief Close the OSS HLS file
  3. */
  4. int oss_media_hls_close(oss_media_hls_file_t *file);

Note: For the complete code, see GitHub.

Write an HLS file

  1. /**
  2. * @brief Write a frame of data in H.264 or AAC format to the OSS
  3. * @param[in] frame A frame of data in H.264 or AAC format
  4. * @param[out] file HLS file
  5. * @return:
  6. * If 0 is returned, it indicates the operation is successful.
  7. * Otherwise, it indicates an error may have occurred
  8. */
  9. int oss_media_hls_write_frame(oss_media_hls_frame_t *frame, oss_media_hls_file_t *file);

Example project:

  1. static void write_frame(oss_media_hls_file_t *file) {
  2. oss_media_hls_frame_t frame;
  3. FILE *file_h264;
  4. uint8_t *buf_h264;
  5. int len_h264, i;
  6. int cur_pos = -1;
  7. int last_pos = -1;
  8. int video_frame_rate = 30;
  9. int max_size = 10 * 1024 * 1024;
  10. char *h264_file_name = "/path/to/example.h264";
  11. /* Read the H.264 file */
  12. buf_h264 = calloc(max_size, 1);
  13. file_h264 = fopen(h264_file_name, "r");
  14. len_h264 = fread(buf_h264, 1, max_size, file_h264);
  15. /* Initialize the frame struct */
  16. frame.stream_type = st_h264;
  17. frame.pts = 0;
  18. frame.continuity_counter = 1;
  19. frame.key = 1;
  20. /* Tranverse the H.264 data and extract the data of every frame, and then write the data into the OSS */
  21. for (i = 0; i < len_h264; i++) {
  22. /* Determine whether the current location is the starting point of the data of the next frame, that is, the end of the current frame */
  23. if ((buf_h264[i] & 0x0F)==0x00 && buf_h264[i+1]==0x00
  24. && buf_h264[i+2]==0x00 && buf_h264[i+3]==0x01)
  25. {
  26. cur_pos = i;
  27. }
  28. /* 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 */
  29. if (last_pos != -1 && cur_pos > last_pos) {
  30. frame.pts += 90000 / video_frame_rate;
  31. frame.dts = frame.pts;
  32. frame.pos = buf_h264 + last_pos;
  33. frame.end = buf_h264 + cur_pos;
  34. oss_media_hls_write_frame(&frame, file);
  35. }
  36. last_pos = cur_pos;
  37. }
  38. /* Close the object and release the resource */
  39. fclose(file_h264);
  40. free(buf_h264);
  41. }

Note:

  • 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

  1. /**
  2. * @brief Write the header data of the M3U8 object
  3. * @param[in] max_duration The maximum duration of the TS object
  4. * @param[in] sequence The starting number of the TS object
  5. * @param[out] file M3U8 file
  6. * @return:
  7. * If 0 is returned, it indicates the operation was successful.
  8. * Otherwise, if "-1" is returned, it indicates an error may have occurred.
  9. */
  10. void oss_media_hls_begin_m3u8(int32_t max_duration,
  11. int32_t sequence,
  12. oss_media_hls_file_t *file);
  13. /**
  14. * @brief Write the data of the M3U8 object
  15. * @param[in] size Number of the M3U8 items
  16. * @param[in] m3u8 Details of the M3u8 item
  17. * @param[out] file M3U8 file
  18. * @return:
  19. * If 0 is returned, it indicates the operation is successful.
  20. * Otherwise, if "-1" is returned, it indicates an error has occured.
  21. */
  22. int oss_media_hls_write_m3u8(int size,
  23. oss_media_hls_m3u8_info_t m3u8[],
  24. oss_media_hls_file_t *file);
  25. /**
  26. * @brief Write data such as the M3U8 object terminator
  27. * @param[out] file M3U8 file
  28. */
  29. void oss_media_hls_end_m3u8(oss_media_hls_file_t *file);

Example project:

  1. static void write_m3u8() {
  2. char *bucket_name;
  3. char *key;
  4. oss_media_hls_file_t *file;
  5. bucket_name = "<your bucket name>";
  6. key = "<your m3u8 file name>";
  7. /* Open an HLS object to write the M3U8-format data. The object name must end with ".m3u8" */
  8. file = oss_media_hls_open(bucket_name, key, auth_func);
  9. if (file == NULL) {
  10. printf("open m3u8 file[%s] failed.", key);
  11. return;
  12. }
  13. /* Construct the information of three TS objects */
  14. oss_media_hls_m3u8_info_t m3u8[3];
  15. m3u8[0].duration = 9;
  16. memcpy(m3u8[0].url, "video-0.ts", strlen("video-0.ts"));
  17. m3u8[1].duration = 10;
  18. memcpy(m3u8[1].url, "video-1.ts", strlen("video-1.ts"));
  19. /* Write to the M3U8 object
  20. oss_media_hls_begin_m3u8(10, 0, file);
  21. oss_media_hls_write_m3u8(2, m3u8, file);
  22. oss_media_hls_end_m3u8(file);
  23. /* Close the HLS object */
  24. oss_media_hls_close(file);
  25. printf("write m3u8 to oss file succeeded\n");
  26. }

Note:

  • 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.
Thank you! We've received your feedback.