Page 1 of 1

Create playlist for one file that is a full album

Posted: 17 Jan 2021 15:32
by myQwil
Occasionally I will come across audio files that are entire albums instead of being broken down into individual tracks.
Is there currently any way to create a playlist that lists all of the start and stop times of each track, which could then be navigated with VLC's playlist view as if they were individual tracks?

Re: Create playlist for one file that is a full album

Posted: 17 Jan 2021 22:20
by myQwil
After looking into the xspf format, I found that vlc has the following options:

Code: Select all

<vlc:option>start-time=TIME</vlc:option> <vlc:option>stop-time=TIME</vlc:option>
Though it would still be nice if the trackbar focused on the start/stop time specified. If the album is long but the specific track is short, it becomes virtually impossible to seek with the trackbar. And despite specifying a duration for each track, that seems to be ignored and the duration of the full album is displayed instead.

Also, my understanding is that these options only work with a few file formats (avi, mov, mkv, mp4), so if it's an mp3, flac, etc., presumably it won't be a viable option.

Re: Create playlist for one file that is a full album

Posted: 19 Jan 2021 17:46
by myQwil
I ended up making a git patch for this. Probably doesn't warrant a pull request but here it is for anyone interested:

Code: Select all

diff --git a/src/input/es_out.c b/src/input/es_out.c index 5a2b194688..895244bf4b 100644 --- a/src/input/es_out.c +++ b/src/input/es_out.c @@ -2791,8 +2791,12 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) double f_position = va_arg( args, double ); mtime_t i_time = va_arg( args, mtime_t ); mtime_t i_length = va_arg( args, mtime_t ); + int64_t i_run = input_priv(p_sys->p_input)->i_run; - input_SendEventLength( p_sys->p_input, i_length ); + if( i_run ) + input_SendEventLength( p_sys->p_input, i_run ); + else + input_SendEventLength( p_sys->p_input, i_length ); if( !p_sys->b_buffering ) { @@ -2809,6 +2813,14 @@ static int EsOutControlLocked( es_out_t *out, int i_query, va_list args ) if( i_time < 0 ) i_time = 0; + if( i_run ) + { + int64_t i_start = input_priv(p_sys->p_input)->i_start; + i_time -= i_start; + f_position = ( f_position - (double)i_start / i_length ) + * input_priv(p_sys->p_input)->f_ratio; + i_length = i_run; + } if( i_length > 0 ) f_position -= (double)i_delay / i_length; if( f_position < 0 ) diff --git a/src/input/input.c b/src/input/input.c index 1b8a2eb83d..0f2f2fb703 100644 --- a/src/input/input.c +++ b/src/input/input.c @@ -956,7 +956,9 @@ static void StartTitle( input_thread_t * p_input ) priv->i_stop += priv->i_start; } - if( priv->i_start > 0 ) + if( priv->i_start < 0 ) + priv->i_start = 0; + else if( priv->i_start > 0 ) { vlc_value_t s; @@ -971,6 +973,20 @@ static void StartTitle( input_thread_t * p_input ) msg_Warn( p_input, "invalid stop-time ignored" ); priv->i_stop = 0; } + + mtime_t i_duration = priv->p_item->i_duration; + if( i_duration > 0 && ( priv->i_start || priv->i_stop ) ) + { + if( priv->i_stop > i_duration || ( priv->i_start && !priv->i_stop ) ) + priv->i_stop = i_duration; + + priv->i_run = priv->i_stop - priv->i_start; + if( priv->i_run ) + { + priv->f_ratio = (double)i_duration / priv->i_run; + priv->p_item->i_duration = priv->i_run; + } + } priv->b_fast_seek = var_GetBool( p_input, "input-fast-seek" ); } @@ -1987,6 +2003,14 @@ static bool Control( input_thread_t *p_input, } float f_pos = val.f_float; + int64_t i_run = input_priv(p_input)->i_run; + if( i_run ) + { + int64_t i_duration = input_priv(p_input)->f_ratio * i_run; + i_run *= f_pos; + i_run += input_priv(p_input)->i_start; + f_pos = (double)i_run / i_duration; + } if( f_pos < 0.f ) f_pos = 0.f; else if( f_pos > 1.f ) diff --git a/src/input/input_internal.h b/src/input/input_internal.h index af9b35967d..890f7fbfed 100644 --- a/src/input/input_internal.h +++ b/src/input/input_internal.h @@ -100,9 +100,11 @@ typedef struct input_thread_private_t int i_rate; /* Playtime configuration and state */ - int64_t i_start; /* :start-time,0 by default */ - int64_t i_stop; /* :stop-time, 0 if none */ int64_t i_time; /* Current time */ + int64_t i_start; /* :start-time, 0 by default */ + int64_t i_stop; /* :stop-time, 0 if none */ + int64_t i_run; /* :run-time (i_stop - i_start) */ + double f_ratio; /* i_duration / i_run */ bool b_fast_seek;/* :input-fast-seek */ /* Output */ diff --git a/src/input/var.c b/src/input/var.c index 631b571c19..dd339dafb0 100644 --- a/src/input/var.c +++ b/src/input/var.c @@ -624,6 +624,7 @@ static int TimeCallback( vlc_object_t *p_this, char const *psz_cmd, var_SetInteger( p_input, "intf-event", INPUT_EVENT_POSITION ); } + newval.i_int += input_priv(p_input)->i_start; input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, &newval ); return VLC_SUCCESS; }
This makes it so that the trackbar focuses in on the start/stop time specified in the xspf file.
These changes were made in vlc-3.0