static void _consumer_handle_eof(void) { struct track_info *ti; if (ip_is_remote(ip)) { _producer_stop(); _consumer_drain_and_stop(); player_error("lost connection"); return; } if (player_info.ti) player_info.ti->play_count++; if (player_repeat_current) { if (player_cont) { ip_seek(ip, 0); reset_buffer(); } else { _producer_stop(); _consumer_drain_and_stop(); _player_status_changed(); } return; } if (get_next(&ti) == 0) { _producer_unload(); ip = ip_new(ti->filename); _producer_status_update(PS_STOPPED); /* PS_STOPPED, CS_PLAYING */ if (player_cont) { _producer_play(); if (producer_status == PS_UNLOADED) { _consumer_stop(); track_info_unref(ti); file_changed(NULL); } else { /* PS_PLAYING */ file_changed(ti); if (!change_sf(0)) _prebuffer(); } } else { _consumer_drain_and_stop(); file_changed(ti); } } else { _producer_unload(); _consumer_drain_and_stop(); file_changed(NULL); } _player_status_changed(); }
static void __producer_play(void) { if (producer_status == PS_UNLOADED) { struct track_info *ti; if (get_next(&ti) == 0) { int rc; ip = ip_new(ti->filename); rc = ip_open(ip); if (rc) { player_ip_error(rc, "opening file `%s'", ti->filename); ip_delete(ip); track_info_unref(ti); file_changed(NULL); } else { ip_setup(ip); __producer_status_update(PS_PLAYING); file_changed(ti); } } } else if (producer_status == PS_PLAYING) { if (ip_seek(ip, 0.0) == 0) { reset_buffer(); } } else if (producer_status == PS_STOPPED) { int rc; rc = ip_open(ip); if (rc) { player_ip_error(rc, "opening file `%s'", ip_get_filename(ip)); ip_delete(ip); __producer_status_update(PS_UNLOADED); } else { ip_setup(ip); __producer_status_update(PS_PLAYING); } } else if (producer_status == PS_PAUSED) { __producer_status_update(PS_PLAYING); } }
void player_seek(double offset, int relative, int start_playing) { int stopped = 0; player_lock(); if (consumer_status == CS_STOPPED) { stopped = 1; __producer_play(); if (producer_status == PS_PLAYING) { __consumer_play(); if (consumer_status != CS_PLAYING) { __producer_stop(); player_unlock(); return; } else __player_status_changed(); } } if (consumer_status == CS_PLAYING || consumer_status == CS_PAUSED) { double pos, duration, new_pos; int rc; pos = (double)consumer_pos / (double)buffer_second_size(); duration = ip_duration(ip); if (duration < 0) { /* can't seek */ d_print("can't seek\n"); player_unlock(); return; } if (relative) { new_pos = pos + offset; if (new_pos < 0.0) new_pos = 0.0; if (offset > 0.0) { /* seeking forward */ if (new_pos > duration - 5.0) new_pos = duration - 5.0; if (new_pos < 0.0) new_pos = 0.0; if (new_pos < pos - 0.5) { /* must seek at least 0.5s */ d_print("must seek at least 0.5s\n"); player_unlock(); return; } } } else { new_pos = offset; if (new_pos < 0.0) { d_print("seek offset negative\n"); player_unlock(); return; } if (new_pos > duration - 5.0) { new_pos = duration - 5.0; if (new_pos < 0.0) new_pos = 0.0; } } /* d_print("seeking %g/%g (%g from eof)\n", new_pos, duration, duration - new_pos); */ rc = ip_seek(ip, new_pos); if (rc == 0) { d_print("doing op_drop after seek\n"); op_drop(); reset_buffer(); consumer_pos = new_pos * buffer_second_size(); scale_pos = consumer_pos; __consumer_position_update(); if (stopped && !start_playing) { __producer_pause(); __consumer_pause(); __player_status_changed(); } } else { player_ip_error(rc, "seeking in file %s", ip_get_filename(ip)); d_print("error: ip_seek returned %d\n", rc); } } player_unlock(); }