mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-14 00:04:13 +09:00
additional parsing of media playlists
This commit is contained in:
@@ -26,12 +26,22 @@
|
||||
#include "raop.h"
|
||||
#include "airplay_video.h"
|
||||
|
||||
typedef enum playlist_type_e {
|
||||
NONE,
|
||||
VOD,
|
||||
EVENT
|
||||
} playlist_type_t;
|
||||
|
||||
struct media_item_s {
|
||||
char *uri;
|
||||
char *playlist;
|
||||
int num;
|
||||
int count;
|
||||
float duration;
|
||||
char *uri;
|
||||
char *playlist;
|
||||
int num;
|
||||
int count;
|
||||
float duration;
|
||||
bool endlist;
|
||||
playlist_type_t playlist_type;
|
||||
int hls_version;
|
||||
int media_sequence;
|
||||
};
|
||||
|
||||
struct airplay_video_s {
|
||||
@@ -550,12 +560,68 @@ void create_media_data_store(airplay_video_t * airplay_video, char ** uri_list,
|
||||
media_data_store[i].uri = uri_list[i];
|
||||
media_data_store[i].playlist = NULL;
|
||||
media_data_store[i].num = i;
|
||||
media_data_store[i].count = 0;
|
||||
media_data_store[i].duration = 0;
|
||||
media_data_store[i].endlist = false;
|
||||
media_data_store[i].playlist_type = NONE;
|
||||
media_data_store[i].hls_version = 0;
|
||||
media_data_store[i].media_sequence = 0;
|
||||
}
|
||||
airplay_video->media_data_store = media_data_store;
|
||||
airplay_video->num_uri = num_uri;
|
||||
}
|
||||
|
||||
int store_media_playlist(airplay_video_t *airplay_video, char * media_playlist, int *count, float *duration, int num) {
|
||||
|
||||
static int parse_media_playlist(media_item_t *media_item) {
|
||||
const char *ptr = media_item->playlist;
|
||||
char extm3u[] = "#EXTM3U";
|
||||
char extinf[] = "#EXTINF:";
|
||||
char extx[] = "#EXT-X-";
|
||||
char playlist_type[] = "PLAYLIST-TYPE:";
|
||||
char version[] = "VERSION:";
|
||||
char media_sequence[] = "MEDIA-SEQUENCE:";
|
||||
ptr = strstr(ptr, extm3u);
|
||||
if (!ptr) {
|
||||
return -1;
|
||||
}
|
||||
ptr++;
|
||||
while (ptr) {
|
||||
const char *ptr1 = NULL;
|
||||
ptr = strstr(ptr, "#EXT");
|
||||
if (!ptr || !memcmp(ptr, extinf, strlen(extinf))) {
|
||||
break;
|
||||
}
|
||||
ptr = strstr(ptr, extx);
|
||||
if (!ptr) {
|
||||
break;
|
||||
}
|
||||
if ((ptr1 = strstr(ptr, playlist_type))) {
|
||||
ptr1 += strlen(playlist_type);
|
||||
if (!memcmp(ptr1,"VOD", strlen("VOD"))) {
|
||||
media_item->playlist_type = VOD;
|
||||
} else if (!memcmp(ptr1,"EVENT", strlen("EVENT"))) {
|
||||
media_item->playlist_type = EVENT;
|
||||
}
|
||||
ptr1 = NULL;
|
||||
}
|
||||
if ((ptr1 = strstr(ptr, version))) {
|
||||
char *endptr = NULL;
|
||||
ptr1 += strlen(version);
|
||||
media_item->hls_version = (int) strtol(ptr1, &endptr, 10);
|
||||
ptr1 = NULL;
|
||||
}
|
||||
if ((ptr1 = strstr(ptr, media_sequence))) {
|
||||
char *endptr = NULL;
|
||||
ptr1 += strlen(media_sequence);
|
||||
media_item->media_sequence = (int) strtol(ptr1, &endptr, 10);
|
||||
ptr1 = NULL;
|
||||
}
|
||||
ptr += strlen(extx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int store_media_playlist(airplay_video_t *airplay_video, char * media_playlist, int *count, float *duration, bool *endlist, int num) {
|
||||
media_item_t *media_data_store = airplay_video->media_data_store;
|
||||
if ( num < 0 || num >= airplay_video->num_uri) {
|
||||
return -1;
|
||||
@@ -571,9 +637,12 @@ int store_media_playlist(airplay_video_t *airplay_video, char * media_playlist,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
media_data_store[num].playlist = media_playlist;
|
||||
media_data_store[num].count = *count;
|
||||
media_data_store[num].duration = *duration;
|
||||
media_item_t *media_item = &media_data_store[num];
|
||||
media_item->playlist = media_playlist;
|
||||
media_item->count = *count;
|
||||
media_item->duration = *duration;
|
||||
media_item->endlist = *endlist;
|
||||
parse_media_playlist(media_item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -600,19 +669,23 @@ char * get_media_uri_by_num(airplay_video_t *airplay_video, int num) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int analyze_media_playlist(char *playlist, float *duration) {
|
||||
int analyze_media_playlist(char *playlist, float *duration, bool *endlist) {
|
||||
float next;
|
||||
int count = 0;
|
||||
char *ptr = strstr(playlist, "#EXTINF:");
|
||||
*duration = 0.0f;
|
||||
*endlist = false;
|
||||
char *end = NULL;
|
||||
while (ptr != NULL) {
|
||||
char *end;
|
||||
ptr += strlen("#EXTINF:");
|
||||
next = strtof(ptr, &end);
|
||||
*duration += next;
|
||||
count++;
|
||||
ptr = strstr(end, "#EXTINF:");
|
||||
}
|
||||
if (end) {
|
||||
*endlist = (strstr(end, "#EXT-X-ENDLIST"));
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,12 +52,12 @@ int get_next_media_uri_id(airplay_video_t *airplay_video);
|
||||
int get_num_media_uri(airplay_video_t *airplay_video);
|
||||
char *get_media_uri_by_num(airplay_video_t *airplay_video, int num);
|
||||
|
||||
int analyze_media_playlist(char *playlist, float *duration);
|
||||
int analyze_media_playlist(char *playlist, float *duration, bool *endlist);
|
||||
int create_media_uri_table(const char *url_prefix, const char *master_playlist_data,
|
||||
int datalen, char ***media_uri_table, int *num_uri);
|
||||
void store_master_playlist(airplay_video_t *airplay_video, char *master_playlist);
|
||||
char *select_master_playlist_language(airplay_video_t *airplay_video, char *master_playlist);
|
||||
int store_media_playlist(airplay_video_t *airplay_video, char *media_playlist, int *count, float *duration, int num);
|
||||
int store_media_playlist(airplay_video_t *airplay_video, char *media_playlist, int *count, float *duration, bool*endlist, int num);
|
||||
char *get_master_playlist(airplay_video_t *airplay_video);
|
||||
char *get_media_playlist(airplay_video_t *airplay_video, int *count, float *duration, const char *uri);
|
||||
|
||||
|
||||
@@ -672,10 +672,11 @@ http_handler_action(raop_conn_t *conn, http_request_t *request, http_response_t
|
||||
} else {
|
||||
/* this is a media playlist */
|
||||
float duration = 0.0f;
|
||||
int count = analyze_media_playlist(playlist, &duration);
|
||||
bool endlist = false;
|
||||
int count = analyze_media_playlist(playlist, &duration, &endlist);
|
||||
int uri_num = get_next_media_uri_id(airplay_video);
|
||||
--uri_num; // (next num is current num + 1)
|
||||
int ret = store_media_playlist(airplay_video, playlist, &count, &duration, uri_num);
|
||||
int ret = store_media_playlist(airplay_video, playlist, &count, &duration, &endlist, uri_num);
|
||||
if (ret == 1) {
|
||||
logger_log(raop->logger, LOGGER_DEBUG,"media_playlist is a duplicate: do not store");
|
||||
} else if (count) {
|
||||
|
||||
Reference in New Issue
Block a user