mirror of
https://github.com/mpv-player/mpv.git
synced 2025-12-28 05:33:14 +00:00
player: improve exit message in some scenarios
If you played e.g. an audio-only file and something bad happened that interrupted playback, the exit message could say "No files played". This was awkward, so show a different message in this case. Also overhaul how the exit status is reported in order to make this easier. This includes things such as not reporting a playback error when loading playlists (playlists contain no video or audio, which was considered an error). Not sure if I'm happy with this, but for now it seems like a slight improvement.
This commit is contained in:
@@ -41,15 +41,6 @@ enum stop_play_reason {
|
|||||||
PT_ERROR, // play next playlist entry (due to an error)
|
PT_ERROR, // play next playlist entry (due to an error)
|
||||||
};
|
};
|
||||||
|
|
||||||
enum exit_reason {
|
|
||||||
EXIT_NONE,
|
|
||||||
EXIT_QUIT,
|
|
||||||
EXIT_PLAYED,
|
|
||||||
EXIT_ERROR,
|
|
||||||
EXIT_NOTPLAYED,
|
|
||||||
EXIT_SOMENOTPLAYED
|
|
||||||
};
|
|
||||||
|
|
||||||
struct timeline_part {
|
struct timeline_part {
|
||||||
double start;
|
double start;
|
||||||
double source_start;
|
double source_start;
|
||||||
@@ -182,14 +173,19 @@ typedef struct MPContext {
|
|||||||
char *stream_open_filename;
|
char *stream_open_filename;
|
||||||
enum stop_play_reason stop_play;
|
enum stop_play_reason stop_play;
|
||||||
bool playback_initialized; // playloop can be run/is running
|
bool playback_initialized; // playloop can be run/is running
|
||||||
|
int error_playing;
|
||||||
|
|
||||||
// Return code to use with PT_QUIT
|
// Return code to use with PT_QUIT
|
||||||
enum exit_reason quit_player_rc;
|
|
||||||
int quit_custom_rc;
|
int quit_custom_rc;
|
||||||
bool has_quit_custom_rc;
|
bool has_quit_custom_rc;
|
||||||
int error_playing;
|
|
||||||
char **resume_defaults;
|
char **resume_defaults;
|
||||||
|
|
||||||
|
// Global file statistics
|
||||||
|
int files_played; // played without issues (even if stopped by user)
|
||||||
|
int files_errored; // played, but errors happened at one point
|
||||||
|
int files_broken; // couldn't be played at all
|
||||||
|
|
||||||
|
// Current file statistics
|
||||||
int64_t shown_vframes, shown_aframes;
|
int64_t shown_vframes, shown_aframes;
|
||||||
|
|
||||||
struct stream *stream; // stream that was initially opened
|
struct stream *stream; // stream that was initially opened
|
||||||
|
|||||||
@@ -989,7 +989,7 @@ goto_reopen_demuxer: ;
|
|||||||
for (struct playlist_entry *e = pl->first; e; e = e->next)
|
for (struct playlist_entry *e = pl->first; e; e = e->next)
|
||||||
e->stream_flags |= entry_stream_flags;
|
e->stream_flags |= entry_stream_flags;
|
||||||
transfer_playlist(mpctx, pl);
|
transfer_playlist(mpctx, pl);
|
||||||
mpctx->error_playing = 0;
|
mpctx->error_playing = 1;
|
||||||
goto terminate_playback;
|
goto terminate_playback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1179,16 +1179,16 @@ terminate_playback:
|
|||||||
mpctx->playback_initialized = false;
|
mpctx->playback_initialized = false;
|
||||||
|
|
||||||
mp_notify(mpctx, MPV_EVENT_TRACKS_CHANGED, NULL);
|
mp_notify(mpctx, MPV_EVENT_TRACKS_CHANGED, NULL);
|
||||||
|
|
||||||
|
bool nothing_played = !mpctx->shown_aframes && !mpctx->shown_vframes &&
|
||||||
|
mpctx->error_playing <= 0;
|
||||||
struct mpv_event_end_file end_event = {0};
|
struct mpv_event_end_file end_event = {0};
|
||||||
switch (mpctx->stop_play) {
|
switch (mpctx->stop_play) {
|
||||||
case PT_ERROR:
|
case PT_ERROR:
|
||||||
case AT_END_OF_FILE:
|
case AT_END_OF_FILE:
|
||||||
{
|
{
|
||||||
if (mpctx->error_playing >= 0 &&
|
if (mpctx->error_playing >= 0 && nothing_played)
|
||||||
mpctx->shown_aframes == 0 && mpctx->shown_vframes == 0)
|
|
||||||
{
|
|
||||||
mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
|
mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY;
|
||||||
}
|
|
||||||
end_event.error = mpctx->error_playing;
|
end_event.error = mpctx->error_playing;
|
||||||
if (end_event.error < 0) {
|
if (end_event.error < 0) {
|
||||||
end_event.reason = MPV_END_FILE_REASON_ERROR;
|
end_event.reason = MPV_END_FILE_REASON_ERROR;
|
||||||
@@ -1199,8 +1199,7 @@ terminate_playback:
|
|||||||
// Played/paused for longer than 1 second -> ok
|
// Played/paused for longer than 1 second -> ok
|
||||||
mpctx->playing->playback_short =
|
mpctx->playing->playback_short =
|
||||||
playback_start < 0 || mp_time_sec() - playback_start < 1.0;
|
playback_start < 0 || mp_time_sec() - playback_start < 1.0;
|
||||||
mpctx->playing->init_failed =
|
mpctx->playing->init_failed = nothing_played;
|
||||||
end_event.error == MPV_ERROR_NOTHING_TO_PLAY;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1218,6 +1217,14 @@ terminate_playback:
|
|||||||
mpctx->filename = NULL;
|
mpctx->filename = NULL;
|
||||||
mpctx->stream_open_filename = NULL;
|
mpctx->stream_open_filename = NULL;
|
||||||
|
|
||||||
|
if (end_event.error < 0 && nothing_played) {
|
||||||
|
mpctx->files_broken++;
|
||||||
|
} else if (end_event.error < 0) {
|
||||||
|
mpctx->files_errored++;
|
||||||
|
} else {
|
||||||
|
mpctx->files_played++;
|
||||||
|
}
|
||||||
|
|
||||||
talloc_free(tmp);
|
talloc_free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1273,24 +1280,12 @@ struct playlist_entry *mp_next_file(struct MPContext *mpctx, int direction,
|
|||||||
// Return if all done.
|
// Return if all done.
|
||||||
void mp_play_files(struct MPContext *mpctx)
|
void mp_play_files(struct MPContext *mpctx)
|
||||||
{
|
{
|
||||||
mpctx->quit_player_rc = EXIT_NONE;
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
idle_loop(mpctx);
|
idle_loop(mpctx);
|
||||||
if (mpctx->stop_play == PT_QUIT)
|
if (mpctx->stop_play == PT_QUIT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
play_current_file(mpctx);
|
play_current_file(mpctx);
|
||||||
if (mpctx->error_playing < 0) {
|
|
||||||
if (!mpctx->quit_player_rc) {
|
|
||||||
mpctx->quit_player_rc = EXIT_NOTPLAYED;
|
|
||||||
} else if (mpctx->quit_player_rc == EXIT_PLAYED) {
|
|
||||||
mpctx->quit_player_rc = EXIT_SOMENOTPLAYED;
|
|
||||||
}
|
|
||||||
} else if (mpctx->quit_player_rc == EXIT_NOTPLAYED) {
|
|
||||||
mpctx->quit_player_rc = EXIT_SOMENOTPLAYED;
|
|
||||||
} else {
|
|
||||||
mpctx->quit_player_rc = EXIT_PLAYED;
|
|
||||||
}
|
|
||||||
if (mpctx->stop_play == PT_QUIT)
|
if (mpctx->stop_play == PT_QUIT)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,12 @@
|
|||||||
|
|
||||||
static bool terminal_initialized;
|
static bool terminal_initialized;
|
||||||
|
|
||||||
|
enum exit_reason {
|
||||||
|
EXIT_NONE,
|
||||||
|
EXIT_NORMAL,
|
||||||
|
EXIT_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
const char mp_help_text[] =
|
const char mp_help_text[] =
|
||||||
"Usage: mpv [options] [url|path/]filename\n"
|
"Usage: mpv [options] [url|path/]filename\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -161,45 +167,45 @@ void mp_destroy(struct MPContext *mpctx)
|
|||||||
static MP_NORETURN void exit_player(struct MPContext *mpctx,
|
static MP_NORETURN void exit_player(struct MPContext *mpctx,
|
||||||
enum exit_reason how)
|
enum exit_reason how)
|
||||||
{
|
{
|
||||||
int rc;
|
|
||||||
|
|
||||||
#if HAVE_COCOA_APPLICATION
|
#if HAVE_COCOA_APPLICATION
|
||||||
cocoa_set_input_context(NULL);
|
cocoa_set_input_context(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (how != EXIT_NONE) {
|
int rc = 0;
|
||||||
const char *reason;
|
const char *reason = NULL;
|
||||||
switch (how) {
|
|
||||||
case EXIT_SOMENOTPLAYED:
|
if (how == EXIT_ERROR) {
|
||||||
case EXIT_PLAYED:
|
reason = "Fatal error";
|
||||||
reason = "End of file";
|
rc = 1;
|
||||||
break;
|
} else if (how == EXIT_NORMAL) {
|
||||||
case EXIT_NOTPLAYED:
|
if (mpctx->stop_play == PT_QUIT) {
|
||||||
reason = "No files played";
|
|
||||||
break;
|
|
||||||
case EXIT_ERROR:
|
|
||||||
reason = "Fatal error";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
reason = "Quit";
|
reason = "Quit";
|
||||||
|
rc = 0;
|
||||||
|
} else if (mpctx->files_played) {
|
||||||
|
if (mpctx->files_errored || mpctx->files_broken) {
|
||||||
|
reason = "Some errors happened";
|
||||||
|
rc = 3;
|
||||||
|
} else {
|
||||||
|
reason = "End of file";
|
||||||
|
rc = 0;
|
||||||
|
}
|
||||||
|
} else if (mpctx->files_broken && !mpctx->files_errored) {
|
||||||
|
reason = "Errors when loading file";
|
||||||
|
rc = 2;
|
||||||
|
} else if (mpctx->files_errored) {
|
||||||
|
reason = "Interrupted by error";
|
||||||
|
rc = 2;
|
||||||
|
} else {
|
||||||
|
reason = "No files played";
|
||||||
|
rc = 0;
|
||||||
}
|
}
|
||||||
MP_INFO(mpctx, "\nExiting... (%s)\n", reason);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mpctx->has_quit_custom_rc) {
|
if (reason)
|
||||||
|
MP_INFO(mpctx, "\nExiting... (%s)\n", reason);
|
||||||
|
|
||||||
|
if (mpctx->has_quit_custom_rc)
|
||||||
rc = mpctx->quit_custom_rc;
|
rc = mpctx->quit_custom_rc;
|
||||||
} else {
|
|
||||||
switch (how) {
|
|
||||||
case EXIT_ERROR:
|
|
||||||
rc = 1; break;
|
|
||||||
case EXIT_NOTPLAYED:
|
|
||||||
rc = 2; break;
|
|
||||||
case EXIT_SOMENOTPLAYED:
|
|
||||||
rc = 3; break;
|
|
||||||
default:
|
|
||||||
rc = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mp_destroy(mpctx);
|
mp_destroy(mpctx);
|
||||||
|
|
||||||
@@ -527,8 +533,6 @@ int mpv_main(int argc, char *argv[])
|
|||||||
exit_player(mpctx, EXIT_ERROR);
|
exit_player(mpctx, EXIT_ERROR);
|
||||||
|
|
||||||
mp_play_files(mpctx);
|
mp_play_files(mpctx);
|
||||||
|
exit_player(mpctx, EXIT_NORMAL);
|
||||||
exit_player(mpctx, mpctx->stop_play == PT_QUIT ? EXIT_QUIT : mpctx->quit_player_rc);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user