4747
4848#define PING_API_ENDPOINT "/api/v1/ping"
4949
50- #define PEERTUBE_SEARCH_API_ENDPOINT "/api/v1/search/videos?search=%s"
50+ #define PEERTUBE_SEARCH_API_ENDPOINT "/api/v1/search/videos?sort=match& search=%s"
5151#define PEERTUBE_VIDEO_DETAILS_API_ENDPOINT "/api/v1/videos/%s"
52+ #define PEERTUBE_CAPTIONS_API_ENDPOINT "/api/v1/videos/%s/captions"
5253
5354#define INVIDIOUS_SEARCH_API_ENDPOINT "/api/v1/search?type=video&sort=relevance&q=%s"
5455#define INVIDIOUS_VIDEO_DETAILS_API_ENDPOINT "/api/v1/videos/%s?local=true"
56+ #define INVIDIOUS_CAPTIONS_API_ENDPOINT "/api/v1/captions/%s"
5557
5658/* Peertube's .previewPath is an absolute URL without domain, but this can be
5759 * not addressed as the thumbnail request comes right after the video details
@@ -62,6 +64,11 @@ static const char *VIDEO_DETAILS_JSON_SELECTOR[] = {
6264 ".[]|.title,.videoId,.author,(.videoThumbnails[]|select(.quality == \"medium\")|.url),.lengthSeconds"
6365};
6466
67+ static const char * CAPTIONS_JSON_SELECTOR [] = {
68+ "(.data[]|select(.language.id == \"en\")|.captionPath),.data[0].captionPath" ,
69+ "(.captions[]|select(.label==\"English\")|.url),.captions[0].url"
70+ };
71+
6572#define N_VIDEO_DETAILS 5
6673#define VIDEO_NAME 0
6774#define VIDEO_ID 1
@@ -102,11 +109,12 @@ static void load_indicator(char on) {
102109}
103110
104111static void load_video (char * id ) {
112+ strcpy (tmp_buf , id ); /* Make it safe, id points to BUF_8K */
105113 load_indicator (1 );
106114 if (instance_type == PEERTUBE )
107- sprintf ((char * )BUF_1K_ADDR , "%s" PEERTUBE_VIDEO_DETAILS_API_ENDPOINT , url , id );
115+ sprintf ((char * )BUF_1K_ADDR , "%s" PEERTUBE_VIDEO_DETAILS_API_ENDPOINT , url , tmp_buf );
108116 else
109- sprintf ((char * )BUF_1K_ADDR , "%s" INVIDIOUS_VIDEO_DETAILS_API_ENDPOINT , url , id );
117+ sprintf ((char * )BUF_1K_ADDR , "%s" INVIDIOUS_VIDEO_DETAILS_API_ENDPOINT , url , tmp_buf );
110118
111119 surl_start_request (SURL_METHOD_GET , (char * )BUF_1K_ADDR , NULL , 0 );
112120
@@ -117,10 +125,46 @@ static void load_video(char *id) {
117125 goto out ;
118126 }
119127
120- if (surl_get_json ((char * )BUF_1K_ADDR , BUF_1K_SIZE , SURL_HTMLSTRIP_NONE , translit_charset ,
128+ if (surl_get_json ((char * )BUF_8K_ADDR , BUF_8K_SIZE , SURL_HTMLSTRIP_NONE , translit_charset ,
121129 VIDEO_URL_JSON_SELECTOR [instance_type ]) > 0 ) {
130+ char * captions = NULL ;
131+
132+ if (enable_subtitles ) {
133+ if (instance_type == PEERTUBE )
134+ sprintf ((char * )BUF_1K_ADDR , "%s" PEERTUBE_CAPTIONS_API_ENDPOINT , url , tmp_buf );
135+ else
136+ sprintf ((char * )BUF_1K_ADDR , "%s" INVIDIOUS_CAPTIONS_API_ENDPOINT , url , tmp_buf );
137+
138+ surl_start_request (SURL_METHOD_GET , (char * )BUF_1K_ADDR , NULL , 0 );
139+
140+ if (surl_response_ok ()) {
141+ int url_len = strlen (url );
142+
143+ /* Prefix first result with instance URL */
144+ strcpy ((char * )BUF_1K_ADDR , url );
145+ /* Get JSON right after the instance URL */
146+ if (surl_get_json ((char * )(BUF_1K_ADDR + url_len ), BUF_1K_SIZE - url_len ,
147+ SURL_HTMLSTRIP_NONE , translit_charset ,
148+ CAPTIONS_JSON_SELECTOR [instance_type ]) > 0 ) {
149+ char * eol = strchr ((char * )BUF_1K_ADDR , '\n' );
150+ /* Cut at end of first match */
151+ if (eol ) {
152+ * eol = '\0' ;
153+ }
154+ /* If we had an absolute URL without host */
155+ if (((char * )BUF_1K_ADDR )[url_len ] == '/' ) {
156+ /* Pass our built URL */
157+ captions = (char * )BUF_1K_ADDR ;
158+ } else {
159+ /* Pass what the server returned */
160+ captions = (char * )(BUF_1K_ADDR + url_len );
161+ }
162+ }
163+ }
164+
165+ }
122166 load_indicator (0 );
123- stream_url ((char * )BUF_1K_ADDR );
167+ stream_url ((char * )BUF_8K_ADDR , captions );
124168
125169 backup_restore_logo ("r" );
126170 videomode (VIDEOMODE_80COL );
@@ -335,7 +379,7 @@ int main(void) {
335379
336380 screensize (& scrw , & scrh );
337381 set_scrollwindow (20 , scrh );
338-
382+
339383 surl_ping ();
340384 load_config ();
341385
0 commit comments