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:
wm4
2014-10-30 23:54:06 +01:00
parent 733936f376
commit 6ddd2b8e03
3 changed files with 58 additions and 63 deletions

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
} }