📄 playlist.c
字号:
playlist->fd = -1; playlist->control_fd = -1; if (index_buffer) { int num_indices = index_buffer_size / sizeof(int); if (num_indices > global_settings.max_files_in_playlist) num_indices = global_settings.max_files_in_playlist; playlist->max_playlist_size = num_indices; playlist->indices = index_buffer; } else { playlist->max_playlist_size = current_playlist.max_playlist_size; playlist->indices = current_playlist.indices; } playlist->buffer_size = 0; playlist->buffer = NULL; mutex_init(&playlist->control_mutex); } new_playlist(playlist, dir, file); if (file) /* load the playlist file */ add_indices_to_playlist(playlist, temp_buffer, temp_buffer_size); return 0;}/* * Set the specified playlist as the current. * NOTE: You will get undefined behaviour if something is already playing so * remember to stop before calling this. Also, this call will * effectively close your playlist, making it unusable. */int playlist_set_current(struct playlist_info* playlist){ if (!playlist || (check_control(playlist) < 0)) return -1; empty_playlist(¤t_playlist, false); strncpy(current_playlist.filename, playlist->filename, sizeof(current_playlist.filename)); current_playlist.fd = playlist->fd; close(playlist->control_fd); remove(current_playlist.control_filename); if (rename(playlist->control_filename, current_playlist.control_filename) < 0) return -1; current_playlist.control_fd = open(current_playlist.control_filename, O_RDWR); if (current_playlist.control_fd < 0) return -1; current_playlist.control_created = true; current_playlist.dirlen = playlist->dirlen; if (playlist->indices && playlist->indices != current_playlist.indices) memcpy(current_playlist.indices, playlist->indices, playlist->max_playlist_size*sizeof(int)); current_playlist.first_index = playlist->first_index; current_playlist.amount = playlist->amount; current_playlist.last_insert_pos = playlist->last_insert_pos; current_playlist.seed = playlist->seed; current_playlist.shuffle_modified = playlist->shuffle_modified; current_playlist.deleted = playlist->deleted; current_playlist.num_inserted_tracks = playlist->num_inserted_tracks; current_playlist.shuffle_flush = playlist->shuffle_flush; return 0;}/* * Close files and delete control file for non-current playlist. */void playlist_close(struct playlist_info* playlist){ if (!playlist) return; if (playlist->fd >= 0) close(playlist->fd); if (playlist->control_fd >= 0) close(playlist->control_fd); if (playlist->control_created) remove(playlist->control_filename);}/* * Insert track into playlist at specified position (or one of the special * positions). Returns position where track was inserted or -1 if error. */int playlist_insert_track(struct playlist_info* playlist, char *filename, int position, bool queue){ int result; if (!playlist) playlist = ¤t_playlist; if (check_control(playlist) < 0) { splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } result = add_track_to_playlist(playlist, filename, position, queue, -1); if (result != -1) { fsync(playlist->control_fd); mpeg_flush_and_reload_tracks(); } return result;}/* * Insert all tracks from specified directory into playlist. */int playlist_insert_directory(struct playlist_info* playlist, char *dirname, int position, bool queue, bool recurse){ int count = 0; int result; char *count_str; if (!playlist) playlist = ¤t_playlist; if (check_control(playlist) < 0) { splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } if (queue) count_str = str(LANG_PLAYLIST_QUEUE_COUNT); else count_str = str(LANG_PLAYLIST_INSERT_COUNT); display_playlist_count(count, count_str); result = add_directory_to_playlist(playlist, dirname, &position, queue, &count, recurse); fsync(playlist->control_fd); display_playlist_count(count, count_str); mpeg_flush_and_reload_tracks(); return result;}/* * Insert all tracks from specified playlist into dynamic playlist. */int playlist_insert_playlist(struct playlist_info* playlist, char *filename, int position, bool queue){ int fd; int max; char *temp_ptr; char *dir; char *count_str; char temp_buf[MAX_PATH+1]; char trackname[MAX_PATH+1]; int count = 0; int result = 0; if (!playlist) playlist = ¤t_playlist; if (check_control(playlist) < 0) { splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } fd = open(filename, O_RDONLY); if (fd < 0) { splash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR)); return -1; } /* we need the directory name for formatting purposes */ dir = filename; temp_ptr = strrchr(filename+1,'/'); if (temp_ptr) *temp_ptr = 0; else dir = "/"; if (queue) count_str = str(LANG_PLAYLIST_QUEUE_COUNT); else count_str = str(LANG_PLAYLIST_INSERT_COUNT); display_playlist_count(count, count_str); while ((max = read_line(fd, temp_buf, sizeof(temp_buf))) > 0) { /* user abort */#if defined(HAVE_PLAYER_KEYPAD) || defined(HAVE_NEO_KEYPAD) if (button_get(false) == BUTTON_STOP)#else if (button_get(false) == BUTTON_OFF)#endif break; if (temp_buf[0] != '#' && temp_buf[0] != '\0') { int insert_pos; /* we need to format so that relative paths are correctly handled */ if (format_track_path(trackname, temp_buf, sizeof(trackname), max, dir) < 0) { result = -1; break; } insert_pos = add_track_to_playlist(playlist, trackname, position, queue, -1); if (insert_pos < 0) { result = -1; break; } /* Make sure tracks are inserted in correct order if user requests INSERT_FIRST */ if (position == PLAYLIST_INSERT_FIRST || position >= 0) position = insert_pos + 1; count++; if ((count%PLAYLIST_DISPLAY_COUNT) == 0) { display_playlist_count(count, count_str); if (count == PLAYLIST_DISPLAY_COUNT) mpeg_flush_and_reload_tracks(); } } /* let the other threads work */ yield(); } close(fd); fsync(playlist->control_fd); if (temp_ptr) *temp_ptr = '/'; display_playlist_count(count, count_str); mpeg_flush_and_reload_tracks(); return result;}/* * Delete track at specified index. If index is PLAYLIST_DELETE_CURRENT then * we want to delete the current playing track. */int playlist_delete(struct playlist_info* playlist, int index){ int result = 0; if (!playlist) playlist = ¤t_playlist; if (check_control(playlist) < 0) { splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } if (index == PLAYLIST_DELETE_CURRENT) index = playlist->index; result = remove_track_from_playlist(playlist, index, true); if (result != -1) mpeg_flush_and_reload_tracks(); return result;}/* * Move track at index to new_index. Tracks between the two are shifted * appropriately. Returns 0 on success and -1 on failure. */int playlist_move(struct playlist_info* playlist, int index, int new_index){ int result; int seek; bool control_file; bool queue; bool current = false; int r; char filename[MAX_PATH]; if (!playlist) playlist = ¤t_playlist; if (check_control(playlist) < 0) { splash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_ACCESS_ERROR)); return -1; } if (index == new_index) return -1; if (index == playlist->index) /* Moving the current track */ current = true; control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; queue = playlist->indices[index] & PLAYLIST_QUEUE_MASK; seek = playlist->indices[index] & PLAYLIST_SEEK_MASK; if (get_filename(playlist, seek, control_file, filename, sizeof(filename)) < 0) return -1; /* Delete track from original position */ result = remove_track_from_playlist(playlist, index, true); if (result != -1) { /* We want to insert the track at the position that was specified by new_index. This may be different then new_index because of the shifting that occurred after the delete */ r = rotate_index(playlist, new_index); if (r == 0) /* First index */ new_index = PLAYLIST_PREPEND; else if (r == playlist->amount) /* Append */ new_index = PLAYLIST_INSERT_LAST; else /* Calculate index of desired position */ new_index = (r+playlist->first_index)%playlist->amount; result = add_track_to_playlist(playlist, filename, new_index, queue, -1); if (result != -1) { if (current) { /* Moved the current track */ switch (new_index) { case PLAYLIST_PREPEND: playlist->index = playlist->first_index; break; case PLAYLIST_INSERT_LAST: playlist->index = playlist->first_index - 1; if (playlist->index < 0) playlist->index += playlist->amount; break; default: playlist->index = new_index; break; } } fsync(playlist->control_fd); mpeg_flush_and_reload_tracks(); } } return result;}/* shuffle currently playing playlist */int playlist_randomise(struct playlist_info* playlist, unsigned int seed, bool start_current){ int result; if (!playlist) playlist = ¤t_playlist; check_control(playlist); result = randomise_playlist(playlist, seed, start_current, true); if (result != -1) mpeg_flush_and_reload_tracks(); return result;}/* sort currently playing playlist */int playlist_sort(struct playlist_info* playlist, bool start_current){ int result; if (!playlist) playlist = ¤t_playlist; check_control(playlist); result = sort_playlist(playlist, start_current, true); if (result != -1) mpeg_flush_and_reload_tracks(); return result;}/* returns true if playlist has been modified */bool playlist_modified(struct playlist_info* playlist){ if (!playlist) playlist = ¤t_playlist; if (playlist->shuffle_modified || playlist->deleted || playlist->num_inserted_tracks > 0) return true;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -