Commit b0ba9c4c authored by Felix Paul Kühne's avatar Felix Paul Kühne

libvlc: expand media player API to retrieve full information about available...

libvlc: expand media player API to retrieve full information about available chapter of a given title
parent 8bb74ef5
...@@ -120,7 +120,8 @@ libVLC: ...@@ -120,7 +120,8 @@ libVLC:
identifier (if there is one available) identifier (if there is one available)
* Add libvlc_media_get_type to get the type of the media * Add libvlc_media_get_type to get the type of the media
* Add libvlc_media_player_get_full_title_descriptions to get full title info of the media * Add libvlc_media_player_get_full_title_descriptions to get full title info of the media
* Deprecate libvlc_video_get_title_description * Add libvlc_media_player_get_full_chapter_descriptions to get full chapter info of the media
* Deprecate libvlc_video_get_title_description, libvlc_video_get_chapter_description
Logging Logging
* Support for the SystemD Journal * Support for the SystemD Journal
......
...@@ -72,6 +72,18 @@ typedef struct libvlc_title_description_t ...@@ -72,6 +72,18 @@ typedef struct libvlc_title_description_t
bool b_menu; bool b_menu;
} libvlc_title_description_t; } libvlc_title_description_t;
/**
* Description for chapters.
* It contains information about time offset, duration
* (both in milliseconds) as well as name (description string).
*/
typedef struct libvlc_chapter_description_t
{
int64_t i_time_offset;
int64_t i_duration;
char *psz_name;
} libvlc_chapter_description_t;
/** /**
* Description for audio output. It contains * Description for audio output. It contains
* name, description and pointer to next record. * name, description and pointer to next record.
...@@ -1169,6 +1181,35 @@ LIBVLC_API ...@@ -1169,6 +1181,35 @@ LIBVLC_API
void libvlc_title_descriptions_release( libvlc_title_description_t **p_titles, void libvlc_title_descriptions_release( libvlc_title_description_t **p_titles,
unsigned i_count ); unsigned i_count );
/**
* Get the full description of available chapters
*
* \version LibVLC 3.0.0 and later.
*
* \param p_mi the media player
* \param index of the title to query for chapters
* \param address to store an allocated array of chapter descriptions
* descriptions (must be freed with libvlc_chapter_descriptions_release()
* by the caller) [OUT]
*
* \return the number of chapters (-1 on error)
*/
LIBVLC_API int libvlc_media_player_get_full_chapter_descriptions( libvlc_media_player_t *p_mi,
int i_chapters_of_title,
libvlc_chapter_description_t *** pp_chapters );
/**
* Release a chapter description
*
* \version LibVLC 3.0.0 and later
*
* \param chapter description array to release
* \param number of chapter descriptions to release
*/
LIBVLC_API
void libvlc_chapter_descriptions_release( libvlc_chapter_description_t **p_chapters,
unsigned i_count );
/** /**
* Get the description of available chapters for specific title. * Get the description of available chapters for specific title.
* *
...@@ -1177,7 +1218,7 @@ LIBVLC_API ...@@ -1177,7 +1218,7 @@ LIBVLC_API
* \return list containing description of available chapter for title i_title. * \return list containing description of available chapter for title i_title.
* It must be freed with libvlc_track_description_list_release() * It must be freed with libvlc_track_description_list_release()
*/ */
LIBVLC_API libvlc_track_description_t * LIBVLC_DEPRECATED LIBVLC_API libvlc_track_description_t *
libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi, int i_title ); libvlc_video_get_chapter_description( libvlc_media_player_t *p_mi, int i_title );
/** /**
......
...@@ -455,6 +455,9 @@ enum input_query_e ...@@ -455,6 +455,9 @@ enum input_query_e
INPUT_GET_TITLE_INFO, /* arg1=input_title_t** arg2= int * res=can fail */ INPUT_GET_TITLE_INFO, /* arg1=input_title_t** arg2= int * res=can fail */
INPUT_GET_FULL_TITLE_INFO, /* arg1=input_title_t*** arg2= int * res=can fail */ INPUT_GET_FULL_TITLE_INFO, /* arg1=input_title_t*** arg2= int * res=can fail */
/* seekpoints */
INPUT_GET_SEEKPOINTS, /* arg1=seekpoint_t*** arg2= int * res=can fail */
/* Attachments */ /* Attachments */
INPUT_GET_ATTACHMENTS, /* arg1=input_attachment_t***, arg2=int* res=can fail */ INPUT_GET_ATTACHMENTS, /* arg1=input_attachment_t***, arg2=int* res=can fail */
INPUT_GET_ATTACHMENT, /* arg1=input_attachment_t**, arg2=char* res=can fail */ INPUT_GET_ATTACHMENT, /* arg1=input_attachment_t**, arg2=char* res=can fail */
......
...@@ -44,6 +44,7 @@ libvlc_audio_set_format ...@@ -44,6 +44,7 @@ libvlc_audio_set_format
libvlc_audio_set_format_callbacks libvlc_audio_set_format_callbacks
libvlc_audio_set_callbacks libvlc_audio_set_callbacks
libvlc_audio_set_volume_callback libvlc_audio_set_volume_callback
libvlc_chapter_descriptions_release
libvlc_clock libvlc_clock
libvlc_event_attach libvlc_event_attach
libvlc_event_detach libvlc_event_detach
...@@ -149,6 +150,7 @@ libvlc_media_player_get_chapter ...@@ -149,6 +150,7 @@ libvlc_media_player_get_chapter
libvlc_media_player_get_chapter_count libvlc_media_player_get_chapter_count
libvlc_media_player_get_chapter_count_for_title libvlc_media_player_get_chapter_count_for_title
libvlc_media_player_get_fps libvlc_media_player_get_fps
libvlc_media_player_get_full_chapter_descriptions
libvlc_media_player_get_full_title_descriptions libvlc_media_player_get_full_title_descriptions
libvlc_media_player_get_hwnd libvlc_media_player_get_hwnd
libvlc_media_player_get_length libvlc_media_player_get_length
......
...@@ -1408,6 +1408,92 @@ void libvlc_title_descriptions_release( libvlc_title_description_t **p_titles, ...@@ -1408,6 +1408,92 @@ void libvlc_title_descriptions_release( libvlc_title_description_t **p_titles,
free( p_titles ); free( p_titles );
} }
int libvlc_media_player_get_full_chapter_descriptions( libvlc_media_player_t *p_mi,
int i_chapters_of_title,
libvlc_chapter_description_t *** pp_chapters )
{
assert( p_mi );
input_thread_t *p_input_thread = libvlc_get_input_thread( p_mi );
if( !p_input_thread )
return -1;
seekpoint_t **p_seekpoint = NULL;
/* fetch data */
int ret = input_Control(p_input_thread, INPUT_GET_SEEKPOINTS, &p_seekpoint, &i_chapters_of_title);
vlc_object_release( p_input_thread );
if( ret != VLC_SUCCESS)
{
return -1;
}
if (i_chapters_of_title == 0 || p_seekpoint == NULL)
{
return 0;
}
const int ci_chapter_count = (const int)i_chapters_of_title;
*pp_chapters = calloc( ci_chapter_count, sizeof(**pp_chapters) );
if( !*pp_chapters )
{
return -1;
}
/* fill array */
for( int i = 0; i < ci_chapter_count; i++)
{
libvlc_chapter_description_t *p_chapter = calloc( 1, sizeof(*p_chapter) );
if( unlikely(p_chapter == NULL) )
{
libvlc_chapter_descriptions_release( *pp_chapters, ci_chapter_count );
free( p_chapter );
return -1;
}
(*pp_chapters)[i] = p_chapter;
p_chapter->i_time_offset = p_seekpoint[i]->i_time_offset / 1000;
if( i > 0 )
{
p_chapter->i_duration = p_chapter->i_time_offset - (*pp_chapters)[i-1]->i_time_offset;
}
else
{
p_chapter->i_duration = p_chapter->i_time_offset;
}
if( p_seekpoint[i]->psz_name )
{
p_chapter->psz_name = strdup( p_seekpoint[i]->psz_name );
}
else
{
p_chapter->psz_name = NULL;
}
vlc_seekpoint_Delete( p_seekpoint[i] );
}
return ci_chapter_count;
}
void libvlc_chapter_descriptions_release( libvlc_chapter_description_t **p_chapters,
unsigned i_count )
{
for (unsigned i = 0; i < i_count; i++ )
{
if ( !p_chapters[i] )
continue;
free( p_chapters[i]->psz_name );
free( p_chapters[i] );
}
free( p_chapters );
}
void libvlc_media_player_next_chapter( libvlc_media_player_t *p_mi ) void libvlc_media_player_next_chapter( libvlc_media_player_t *p_mi )
{ {
input_thread_t *p_input_thread; input_thread_t *p_input_thread;
......
...@@ -391,6 +391,50 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args ) ...@@ -391,6 +391,50 @@ int input_vaControl( input_thread_t *p_input, int i_query, va_list args )
return VLC_SUCCESS; return VLC_SUCCESS;
} }
case INPUT_GET_SEEKPOINTS:
{
seekpoint_t ***array = (seekpoint_t ***)va_arg( args, seekpoint_t *** );
int *pi_title_to_fetch = (int *) va_arg( args, int * );
vlc_mutex_lock( &p_input->p->p_item->lock );
if ( *pi_title_to_fetch < 0 ) /* query current title if -1 */
*pi_title_to_fetch = var_GetInteger( p_input, "title" );
if( !p_input->p->i_title || p_input->p->i_title < *pi_title_to_fetch )
{
vlc_mutex_unlock( &p_input->p->p_item->lock );
return VLC_EGENERIC;
}
input_title_t *p_title = vlc_input_title_Duplicate( p_input->p->title[*pi_title_to_fetch] );
/* set arg2 to the number of seekpoints we found */
const int i_chapters = p_title->i_seekpoint;
*pi_title_to_fetch = i_chapters;
if ( i_chapters == 0 )
{
vlc_mutex_unlock( &p_input->p->p_item->lock );
return VLC_SUCCESS;
}
*array = calloc( p_title->i_seekpoint, sizeof(**array) );
if( !array )
{
vlc_mutex_unlock( &p_input->p->p_item->lock );
return VLC_ENOMEM;
}
for( int i = 0; i < i_chapters; i++ )
{
(*array)[i] = vlc_seekpoint_Duplicate( p_title->seekpoint[i] );
}
vlc_mutex_unlock( &p_input->p->p_item->lock );
return VLC_SUCCESS;
}
case INPUT_GET_VIDEO_FPS: case INPUT_GET_VIDEO_FPS:
pf = (double*)va_arg( args, double * ); pf = (double*)va_arg( args, double * );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment