mirror of
https://github.com/mpv-player/mpv
synced 2024-12-24 07:42:17 +00:00
command, dvd: add property which returns list of DVD titles
This was requested. It seems libdvdread can't get the duration for titlesets other than the currently opened title. The data structures contain dangling pointers for these, and MPlayer works this around by opening every title separately for the purpose of dumping the title list.
This commit is contained in:
parent
c3275f7e53
commit
5b618ef629
@ -773,6 +773,33 @@ Property list
|
||||
``disc-titles``
|
||||
Number of BD/DVD titles.
|
||||
|
||||
This has a number of sub-properties. Replace ``N`` with the 0-based edition
|
||||
index.
|
||||
|
||||
``disc-titles/count``
|
||||
Number of titles.
|
||||
|
||||
``disc-titles/id``
|
||||
Title ID as integer. Currently, this is the same as the title index.
|
||||
|
||||
``disc-titles/length``
|
||||
Length in seconds. Can be unavailable in a number of cases (currently
|
||||
it works for libdvdnav only).
|
||||
|
||||
When querying the property with the client API using ``MPV_FORMAT_NODE``,
|
||||
or with Lua ``mp.get_property_native``, this will return a mpv_node with
|
||||
the following contents:
|
||||
|
||||
::
|
||||
|
||||
MPV_FORMAT_NODE_ARRAY
|
||||
MPV_FORMAT_NODE_MAP (for each edition)
|
||||
"id" MPV_FORMAT_INT64
|
||||
"length" MPV_FORMAT_DOUBLE
|
||||
|
||||
``disc-title-list``
|
||||
List of BD/DVD titles.
|
||||
|
||||
``disc-title`` (RW)
|
||||
Current BD/DVD title number. Writing works only for ``dvdnav://`` and
|
||||
``bd://`` (and aliases for these).
|
||||
|
@ -910,6 +910,38 @@ static int mp_property_disc_titles(void *ctx, struct m_property *prop,
|
||||
return m_property_int_ro(action, arg, num_titles);
|
||||
}
|
||||
|
||||
static int get_disc_title_entry(int item, int action, void *arg, void *ctx)
|
||||
{
|
||||
struct MPContext *mpctx = ctx;
|
||||
struct demuxer *demuxer = mpctx->master_demuxer;
|
||||
|
||||
double len = item;
|
||||
if (demux_stream_control(demuxer, STREAM_CTRL_GET_TITLE_LENGTH, &len) < 1)
|
||||
len = -1;
|
||||
|
||||
struct m_sub_property props[] = {
|
||||
{"id", SUB_PROP_INT(item)},
|
||||
{"length", {.type = CONF_TYPE_TIME}, {.time = len},
|
||||
.unavailable = len < 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
return m_property_read_sub(props, action, arg);
|
||||
}
|
||||
|
||||
static int mp_property_list_disc_titles(void *ctx, struct m_property *prop,
|
||||
int action, void *arg)
|
||||
{
|
||||
MPContext *mpctx = ctx;
|
||||
struct demuxer *demuxer = mpctx->master_demuxer;
|
||||
unsigned int num_titles;
|
||||
if (!demuxer || demux_stream_control(demuxer, STREAM_CTRL_GET_NUM_TITLES,
|
||||
&num_titles) < 1)
|
||||
return M_PROPERTY_UNAVAILABLE;
|
||||
return m_property_read_list(action, arg, num_titles,
|
||||
get_disc_title_entry, mpctx);
|
||||
}
|
||||
|
||||
/// Number of chapters in file
|
||||
static int mp_property_chapters(void *ctx, struct m_property *prop,
|
||||
int action, void *arg)
|
||||
@ -3227,6 +3259,7 @@ static const struct m_property mp_properties[] = {
|
||||
{"chapter-list", mp_property_list_chapters},
|
||||
{"track-list", property_list_tracks},
|
||||
{"edition-list", property_list_editions},
|
||||
{"disc-title-list", mp_property_list_disc_titles},
|
||||
|
||||
{"playlist", mp_property_playlist},
|
||||
{"playlist-pos", mp_property_playlist_pos},
|
||||
|
@ -65,33 +65,28 @@ enum streamtype {
|
||||
#define STREAM_OK 1
|
||||
|
||||
enum stream_ctrl {
|
||||
STREAM_CTRL_GET_TIME_LENGTH = 1,
|
||||
STREAM_CTRL_GET_NUM_CHAPTERS,
|
||||
STREAM_CTRL_GET_CURRENT_TIME,
|
||||
STREAM_CTRL_SEEK_TO_TIME,
|
||||
STREAM_CTRL_GET_SIZE,
|
||||
STREAM_CTRL_GET_ASPECT_RATIO,
|
||||
STREAM_CTRL_GET_NUM_ANGLES,
|
||||
STREAM_CTRL_GET_ANGLE,
|
||||
STREAM_CTRL_SET_ANGLE,
|
||||
STREAM_CTRL_GET_NUM_TITLES,
|
||||
STREAM_CTRL_GET_LANG,
|
||||
STREAM_CTRL_GET_CURRENT_TITLE,
|
||||
STREAM_CTRL_SET_CURRENT_TITLE,
|
||||
STREAM_CTRL_GET_SIZE = 1,
|
||||
|
||||
// Cache
|
||||
STREAM_CTRL_GET_CACHE_SIZE,
|
||||
STREAM_CTRL_SET_CACHE_SIZE,
|
||||
STREAM_CTRL_GET_CACHE_FILL,
|
||||
STREAM_CTRL_GET_CACHE_IDLE,
|
||||
STREAM_CTRL_RESUME_CACHE,
|
||||
STREAM_CTRL_RECONNECT,
|
||||
STREAM_CTRL_GET_CHAPTER_TIME,
|
||||
STREAM_CTRL_GET_DVD_INFO,
|
||||
|
||||
// stream_memory.c
|
||||
STREAM_CTRL_SET_CONTENTS,
|
||||
STREAM_CTRL_GET_METADATA,
|
||||
|
||||
// stream_rar.c
|
||||
STREAM_CTRL_GET_BASE_FILENAME,
|
||||
STREAM_CTRL_GET_NAV_EVENT, // struct mp_nav_event**
|
||||
STREAM_CTRL_NAV_CMD, // struct mp_nav_cmd*
|
||||
STREAM_CTRL_GET_DISC_NAME,
|
||||
|
||||
// Certain network protocols
|
||||
STREAM_CTRL_RECONNECT,
|
||||
STREAM_CTRL_AVSEEK,
|
||||
STREAM_CTRL_HAS_AVSEEK,
|
||||
STREAM_CTRL_GET_METADATA,
|
||||
|
||||
// TV
|
||||
STREAM_CTRL_TV_SET_SCAN,
|
||||
STREAM_CTRL_SET_TV_FREQ,
|
||||
STREAM_CTRL_GET_TV_FREQ,
|
||||
@ -104,8 +99,26 @@ enum stream_ctrl {
|
||||
STREAM_CTRL_TV_LAST_CHAN,
|
||||
STREAM_CTRL_DVB_SET_CHANNEL,
|
||||
STREAM_CTRL_DVB_STEP_CHANNEL,
|
||||
STREAM_CTRL_AVSEEK,
|
||||
STREAM_CTRL_HAS_AVSEEK,
|
||||
|
||||
// Optical discs
|
||||
STREAM_CTRL_GET_TIME_LENGTH,
|
||||
STREAM_CTRL_GET_DVD_INFO,
|
||||
STREAM_CTRL_GET_NAV_EVENT, // struct mp_nav_event**
|
||||
STREAM_CTRL_NAV_CMD, // struct mp_nav_cmd*
|
||||
STREAM_CTRL_GET_DISC_NAME,
|
||||
STREAM_CTRL_GET_NUM_CHAPTERS,
|
||||
STREAM_CTRL_GET_CURRENT_TIME,
|
||||
STREAM_CTRL_GET_CHAPTER_TIME,
|
||||
STREAM_CTRL_SEEK_TO_TIME,
|
||||
STREAM_CTRL_GET_ASPECT_RATIO,
|
||||
STREAM_CTRL_GET_NUM_ANGLES,
|
||||
STREAM_CTRL_GET_ANGLE,
|
||||
STREAM_CTRL_SET_ANGLE,
|
||||
STREAM_CTRL_GET_NUM_TITLES,
|
||||
STREAM_CTRL_GET_TITLE_LENGTH, // double* (in: title number, out: len)
|
||||
STREAM_CTRL_GET_LANG,
|
||||
STREAM_CTRL_GET_CURRENT_TITLE,
|
||||
STREAM_CTRL_SET_CURRENT_TITLE,
|
||||
};
|
||||
|
||||
struct stream_lang_req {
|
||||
|
@ -541,6 +541,18 @@ static int control(stream_t *stream,int cmd,void* arg)
|
||||
*((unsigned int *)arg) = d->vmg_file->tt_srpt->nr_of_srpts;
|
||||
return 1;
|
||||
}
|
||||
case STREAM_CTRL_GET_TITLE_LENGTH:
|
||||
{
|
||||
int t = *(double *)arg;
|
||||
if (t < 0 || t >= d->vmg_file->tt_srpt->nr_of_srpts)
|
||||
break;
|
||||
if (d->tt_srpt->title[t].title_set_nr !=
|
||||
d->tt_srpt->title[d->dvd_title].title_set_nr)
|
||||
break;
|
||||
*(double *)arg =
|
||||
mp_get_titleset_length(d->vts_file, d->tt_srpt, t) / 1000.0;
|
||||
return 1;
|
||||
}
|
||||
case STREAM_CTRL_GET_NUM_CHAPTERS:
|
||||
{
|
||||
int r;
|
||||
|
@ -535,6 +535,22 @@ static int control(stream_t *stream, int cmd, void *arg)
|
||||
*((unsigned int*)arg)= num_titles;
|
||||
return STREAM_OK;
|
||||
}
|
||||
case STREAM_CTRL_GET_TITLE_LENGTH: {
|
||||
int t = *(double *)arg;
|
||||
int32_t num_titles = 0;
|
||||
if (dvdnav_get_number_of_titles(dvdnav, &num_titles) != DVDNAV_STATUS_OK)
|
||||
break;
|
||||
if (t < 0 || t >= num_titles)
|
||||
break;
|
||||
uint64_t duration = 0;
|
||||
uint64_t *parts = NULL;
|
||||
dvdnav_describe_title_chapters(dvdnav, t + 1, &parts, &duration);
|
||||
if (!parts)
|
||||
break;
|
||||
free(parts);
|
||||
*(double *)arg = duration / 90000.0;
|
||||
return STREAM_OK;
|
||||
}
|
||||
case STREAM_CTRL_GET_CURRENT_TITLE: {
|
||||
if (dvdnav_current_title_info(dvdnav, &tit, &part) != DVDNAV_STATUS_OK)
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user