Пример #1
0
/* Start playback of a playlist, checking for bookmark autoload, modified
 * playlists, etc., as required. Returns false if playback wasn't started,
 * or started via bookmark autoload, true otherwise.
 *
 * Pointers to both the full pathname and the separated parts needed to
 * avoid allocating yet another path buffer on the stack (and save some 
 * code; the caller typically needs to create the full pathname anyway)...
 */
bool ft_play_playlist(char* pathname, char* dirname, char* filename)
{
    if (global_settings.party_mode && audio_status()) 
    {
        splash(HZ, ID2P(LANG_PARTY_MODE));
        return false;
    }

    if (bookmark_autoload(pathname))
    {
        return false;
    }

    splash(0, ID2P(LANG_WAIT));

    /* about to create a new current playlist...
       allow user to cancel the operation */
    if (!warn_on_pl_erase())
        return false;

    if (playlist_create(dirname, filename) != -1)
    {
        if (global_settings.playlist_shuffle)
        {
            playlist_shuffle(current_tick, -1);
        }
        
        playlist_start(0, 0);
        return true;
    }
    
    return false;
}
Пример #2
0
Файл: fb.c Проект: gettler/mvpmc
void
fb_shuffle(int shuffle)
{
	char **item, *tmp;
	int i, j, k, n;

	if (shuffle)
		mvpw_set_menu_title(playlist_widget, "Shuffle Play");
	else
		mvpw_set_menu_title(playlist_widget, "Play All");
	
	item = alloca(sizeof(char*) * MAX_PLAYLIST_ENTRIES);

	// Recurse from the current directory and find all
	// audio files
	n = 0;
	recurse_find_audio(cwd, item, &n);
	
	if (n == 0) {
		gui_error("No audio files exist in this directory or its subdirectories");
		return;
	}

	if (shuffle && (n > 1)) {
		for (i=0; i < MAX_PLAYLIST_ENTRIES; i++) {
			j = rand() % n;
			k = rand() % n;
			tmp = item[k];
			item[k] = item[j];
			item[j] = tmp;
		}
	}

	printf("created playlist of %d songs\n", n);

	switch_hw_state(MVPMC_STATE_FILEBROWSER);
	video_functions = &file_functions;

	playlist_clear();

	mvpw_show(playlist_widget);
	mvpw_focus(playlist_widget);

	playlist_create(item, n);

	// Release the list of items
	for (i = 0; i < n; i++)
		free(item[i]);

	if (shuffle)
		mvpw_set_text_str(fb_name, "Shuffle Play");
	else
		mvpw_set_text_str(fb_name, "Play All");

	mvpw_show(fb_progress);
	mvpw_set_timer(fb_progress, fb_osd_update, 500);
	playlist_play(NULL);
}
Пример #3
0
playlist_t *
playlist_program(const char *filename)
{
	playlist_t	*pl;
#ifdef HAVE_STAT
	struct stat	 st;
#else
	FILE		*filep;
#endif

	pl = playlist_create(filename);
	pl->program = 1;

#ifdef HAVE_STAT
	if (stat(filename, &st) == -1) {
		printf("%s: %s: %s\n", __progname, filename, strerror(errno));
		playlist_free(&pl);
		return (NULL);
	}
	if (st.st_mode & (S_IWGRP | S_IWOTH)) {
		printf("%s: Error: %s is group and/or world writeable\n",
		       __progname, filename);
		playlist_free(&pl);
		return (NULL);
	}
	if (!(st.st_mode & (S_IEXEC | S_IXGRP | S_IXOTH))) {
		printf("%s: %s: Not an executable program\n", __progname, filename);
		playlist_free(&pl);
		return (NULL);
	}
#else
	if ((filep = fopen(filename, "r")) == NULL) {
		printf("%s: %s: %s\n", __progname, filename, strerror(errno));
		playlist_free(&pl);
		return (NULL);
	}
	fclose(filep);
#endif /* HAVE_STAT */

	return (pl);
}
Пример #4
0
/* CONTEXT_[TREE|ID3DB] playlist options */
static bool add_to_playlist(int position, bool queue)
{
    bool new_playlist = !(audio_status() & AUDIO_STATUS_PLAY);
    const char *lines[] = {
        ID2P(LANG_RECURSE_DIRECTORY_QUESTION),
        selected_file
    };
    const struct text_message message={lines, 2};

    splash(0, ID2P(LANG_WAIT));

    if (new_playlist)
        playlist_create(NULL, NULL);

    /* always set seed before inserting shuffled */
    if (position == PLAYLIST_INSERT_SHUFFLED ||
        position == PLAYLIST_INSERT_LAST_SHUFFLED)
    {
        srand(current_tick);
        if (position == PLAYLIST_INSERT_LAST_SHUFFLED)
            playlist_set_last_shuffled_start();
    }

#ifdef HAVE_TAGCACHE
    if (context == CONTEXT_ID3DB)
    {
        tagtree_insert_selection_playlist(position, queue);
    }
    else
#endif
    {
        if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_AUDIO)
            playlist_insert_track(NULL, selected_file, position, queue, true);
        else if (selected_file_attr & ATTR_DIRECTORY)
        {
            bool recurse = false;

            if (global_settings.recursive_dir_insert != RECURSE_ASK)
                recurse = (bool)global_settings.recursive_dir_insert;
            else
            {
                /* Ask if user wants to recurse directory */
                recurse = (gui_syncyesno_run(&message, NULL, NULL)==YESNO_YES);
            }

            playlist_insert_directory(NULL, selected_file, position, queue,
                                      recurse);
        }
        else if ((selected_file_attr & FILE_ATTR_MASK) == FILE_ATTR_M3U)
            playlist_insert_playlist(NULL, selected_file, position, queue);
    }

    if (new_playlist && (playlist_amount() > 0))
    {
        /* nothing is currently playing so begin playing what we just
           inserted */
        if (global_settings.playlist_shuffle)
            playlist_shuffle(current_tick, -1);
        playlist_start(0,0);
        onplay_result = ONPLAY_START_PLAY;
    }

    return false;
}
Пример #5
0
playlist_t *
playlist_read(const char *filename)
{
	playlist_t	*pl;
	unsigned long	 line;
	FILE		*filep;
	char		 buf[PATH_MAX];

	if (filename != NULL) {
		pl = playlist_create(filename);

		if ((filep = fopen(filename, "r")) == NULL) {
			printf("%s: %s: %s\n", __progname, filename, strerror(errno));
			playlist_free(&pl);
			return (NULL);
		}
	} else {
		pl = playlist_create("stdin");

		if ((filep = fdopen(STDIN_FILENO, "r")) == NULL) {
			printf("%s: stdin: %s\n", __progname, strerror(errno));
			playlist_free(&pl);
			return (NULL);
		}
	}

	line = 0;
	while (fgets(buf, (int)sizeof(buf), filep) != NULL) {
		line++;

		if (strlen(buf) == sizeof(buf) - 1) {
			char skip_buf[2];

			printf("%s[%lu]: File or path name too long\n",
			       pl->filename, line);
			/* Discard any excess chars in that line. */
			while (fgets(skip_buf, (int)sizeof(skip_buf), filep) != NULL) {
				if (skip_buf[0] == '\n')
					break;
			}
			continue;
		}

		/*
		 * fgets() would happily fill a buffer with
		 * { '\0', ..., '\n', '\0' }. Also skip lines that begin with
		 * a '#', which is considered a comment.
		 */
		if (buf[0] == '\0' || buf[0] == '#')
			continue;

		/* Trim any trailing newlines and carriage returns. */
		buf[strcspn(buf, "\n")] = '\0';
		buf[strcspn(buf, "\r")] = '\0';

		/* Skip lines that are empty after the trimming. */
		if (buf[0] == '\0')
			continue;

		/* We got one. */
		if (!playlist_add(pl, buf)) {
			fclose(filep);
			playlist_free(&pl);
			return (NULL);
		}
	}
	if (ferror(filep)) {
		printf("%s: playlist_read(): Error while reading %s: %s\n",
		       __progname, pl->filename, strerror(errno));
		fclose(filep);
		playlist_free(&pl);
		return (NULL);
	}

	fclose(filep);
	return (pl);
}
Пример #6
0
bool bookmark_play(char *resume_file, int index, int offset, int seed,
                   char *filename)
{
    int i;
    char* suffix = strrchr(resume_file, '.');
    bool started = false;

    if (suffix != NULL &&
        (!strcasecmp(suffix, ".m3u") || !strcasecmp(suffix, ".m3u8")))
    {
        /* Playlist playback */
        char* slash;
        /* check that the file exists */
        if(!file_exists(resume_file))
            return false;

        slash = strrchr(resume_file,'/');
        if (slash)
        {
            char* cp;
            *slash=0;

            cp=resume_file;
            if (!cp[0])
                cp="/";

            if (playlist_create(cp, slash+1) != -1)
            {
                if (global_settings.playlist_shuffle)
                    playlist_shuffle(seed, -1);
                playlist_start(index,offset);
                started = true;
            }
            *slash='/';
        }
    }
    else
    {
        /* Directory playback */
        lastdir[0]='\0';
        if (playlist_create(resume_file, NULL) != -1)
        {
            char filename_buf[MAX_PATH + 1];
            const char* peek_filename;
            resume_directory(resume_file);
            if (global_settings.playlist_shuffle)
                playlist_shuffle(seed, -1);

            /* Check if the file is at the same spot in the directory,
               else search for it */
            peek_filename = playlist_peek(index, filename_buf,
                sizeof(filename_buf));
            
            if (peek_filename == NULL)
            {
                /* playlist has shrunk, search from the top */
                index = 0;
                peek_filename = playlist_peek(index, filename_buf,
                    sizeof(filename_buf));
                if (peek_filename == NULL)
                    return false;
            }
                
            if (strcmp(strrchr(peek_filename, '/') + 1, filename))
            {
                for ( i=0; i < playlist_amount(); i++ )
                {
                    peek_filename = playlist_peek(i, filename_buf,
                        sizeof(filename_buf));

                    if (peek_filename == NULL)
                        return false;

                    if (!strcmp(strrchr(peek_filename, '/') + 1, filename))
                        break;
                }
                if (i < playlist_amount())
                    index = i;
                else
                    return false;
            }
            playlist_start(index,offset);
            started = true;
        }
    }

    if (started)
        start_wps = true;
    return started;
}
Пример #7
0
int main(int argc, char **argv)
{
  int optind;
  char **playlist_array;
  int items;
  struct stat stat_buf;
  int i;

  setlocale(LC_ALL, "");
  bindtextdomain(PACKAGE, LOCALEDIR);
  textdomain(PACKAGE);

  ao_initialize();
  stat_format = stat_format_create();
  options_init(&options);
  file_options_init(file_opts);

  parse_std_configs(file_opts);
  options.playlist = playlist_create();
  optind = parse_cmdline_options(argc, argv, &options, file_opts);

  audio_play_arg.devices = options.devices;
  audio_play_arg.stat_format = stat_format;

  /* Add remaining arguments to playlist */
  for (i = optind; i < argc; i++) {
    if (stat(argv[i], &stat_buf) == 0) {

      if (S_ISDIR(stat_buf.st_mode)) {
	if (playlist_append_directory(options.playlist, argv[i]) == 0)
	  fprintf(stderr, 
		  _("Warning: Could not read directory %s.\n"), argv[i]);
      } else {
	playlist_append_file(options.playlist, argv[i]);
      }
    } else /* If we can't stat it, it might be a non-disk source */
      playlist_append_file(options.playlist, argv[i]);


  }


  /* Do we have anything left to play? */
  if (playlist_length(options.playlist) == 0) {
    cmdline_usage();
    exit(1);
  } else {
    playlist_array = playlist_to_array(options.playlist, &items);
    playlist_destroy(options.playlist);
    options.playlist = NULL;
  }

  /* Don't use status_message until after this point! */
  status_set_verbosity(options.verbosity);

  print_audio_devices_info(options.devices);

  
  /* Setup buffer */ 
  if (options.buffer_size > 0) {
    audio_buffer = buffer_create(options.buffer_size,
				 options.buffer_size * options.prebuffer / 100,
				 audio_play_callback, &audio_play_arg,
				 AUDIO_CHUNK_SIZE);
    if (audio_buffer == NULL) {
      status_error(_("Error: Could not create audio buffer.\n"));
      exit(1);
    }
  } else
    audio_buffer = NULL;


  /* Shuffle playlist */
  if (options.shuffle) {
    int i;
    
    srandom(time(NULL));
    
    for (i = 0; i < items; i++) {
      int j = i + random() % (items - i);
      char *temp = playlist_array[i];
      playlist_array[i] = playlist_array[j];
      playlist_array[j] = temp;
    }
  }

  /* Setup signal handlers and callbacks */

  ATEXIT (exit_cleanup);
  signal (SIGINT, signal_handler);
  signal (SIGTSTP, signal_handler);
  signal (SIGCONT, signal_handler);
  signal (SIGTERM, signal_handler);

  /* Play the files/streams */
  i = 0;
  while (i < items && !sig_request.exit) {
    play(playlist_array[i]);
    i++;
  }

  playlist_array_destroy(playlist_array, items);

  exit (0);
}
Пример #8
0
int ft_enter(struct tree_context* c)
{
    int rc = GO_TO_PREVIOUS;
    char buf[MAX_PATH];
    struct entry* file = tree_get_entry_at(c, c->selected_item);
    int file_attr = file->attr;

    if (c->currdir[1])
        snprintf(buf,sizeof(buf),"%s/%s",c->currdir, file->name);
    else
        snprintf(buf,sizeof(buf),"/%s",file->name);

    if (file_attr & ATTR_DIRECTORY) {
        memcpy(c->currdir, buf, sizeof(c->currdir));
        if ( c->dirlevel < MAX_DIR_LEVELS )
            c->selected_item_history[c->dirlevel] = c->selected_item;
        c->dirlevel++;
        c->selected_item=0;
    }
    else {
        int seed = current_tick;
        bool play = false;
        int start_index=0;

        switch ( file_attr & FILE_ATTR_MASK ) {
            case FILE_ATTR_M3U:
                if (!bookmark_autoload(buf))
                    playlist_viewer_ex(buf);
                break;

            case FILE_ATTR_AUDIO:
                if (bookmark_autoload(c->currdir))
                    break;

                splash(0, ID2P(LANG_WAIT));

                /* about to create a new current playlist...
                   allow user to cancel the operation */
                if (!warn_on_pl_erase())
                    break;

                if (global_settings.party_mode && audio_status()) 
                {
                    playlist_insert_track(NULL, buf,
                                          PLAYLIST_INSERT_LAST, true, true);
                    splash(HZ, ID2P(LANG_QUEUE_LAST));
                }
                else if (playlist_create(c->currdir, NULL) != -1)
                {
                    start_index = ft_build_playlist(c, c->selected_item);
                    if (global_settings.playlist_shuffle)
                    {
                        start_index = playlist_shuffle(seed, start_index);

                        /* when shuffling dir.: play all files
                           even if the file selected by user is
                           not the first one */
                        if (!global_settings.play_selected)
                            start_index = 0;
                    }

                    playlist_start(start_index, 0);
                    play = true;
                }
                break;

#if CONFIG_TUNER
                /* fmr preset file */
            case FILE_ATTR_FMR:
                splash(0, ID2P(LANG_WAIT));

                /* Preset inside the default folder. */
                if(!strncasecmp(FMPRESET_PATH, buf, strlen(FMPRESET_PATH)))
                {
                    set_file(buf, global_settings.fmr_file, MAX_FILENAME);
                    radio_load_presets(global_settings.fmr_file);
                }
                /*
                 * Preset outside default folder, we can choose such only
                 * if we are out of the radio screen, so the check for the
                 * radio status isn't neccessary
                 */
                else
                {
                    radio_load_presets(buf);
                }
                rc = GO_TO_FM;

                break;
            case FILE_ATTR_FMS:
                splash(0, ID2P(LANG_WAIT));
                set_file(buf, (char *)global_settings.fms_file, MAX_FILENAME);
                settings_apply_skins();
                break;
#ifdef HAVE_REMOTE_LCD
            case FILE_ATTR_RFMS:
                splash(0, ID2P(LANG_WAIT));
                set_file(buf, (char *)global_settings.rfms_file, MAX_FILENAME);
                settings_apply_skins();
                break;
#endif
#endif

#ifdef HAVE_LCD_BITMAP
            case FILE_ATTR_SBS:
                splash(0, ID2P(LANG_WAIT));
                set_file(buf, (char *)global_settings.sbs_file, MAX_FILENAME);
                settings_apply_skins();
                break;
#endif
#ifdef HAVE_REMOTE_LCD
            case FILE_ATTR_RSBS:
                splash(0, ID2P(LANG_WAIT));
                set_file(buf, (char *)global_settings.rsbs_file, MAX_FILENAME);
                settings_apply_skins();
                break;
#endif
                /* wps config file */
            case FILE_ATTR_WPS:
                splash(0, ID2P(LANG_WAIT));
                set_file(buf, (char *)global_settings.wps_file,
                         MAX_FILENAME);
                settings_apply_skins();
                break;

#if defined(HAVE_REMOTE_LCD) && (NB_SCREENS > 1)
                /* remote-wps config file */
            case FILE_ATTR_RWPS:
                splash(0, ID2P(LANG_WAIT));
                set_file(buf, (char *)global_settings.rwps_file,
                         MAX_FILENAME);
                settings_apply_skins();
                break;
#endif

            case FILE_ATTR_CFG:
                splash(0, ID2P(LANG_WAIT));
                if (!settings_load_config(buf,true))
                    break;
                splash(HZ, ID2P(LANG_SETTINGS_LOADED));
                break;

            case FILE_ATTR_BMARK:
                splash(0, ID2P(LANG_WAIT));
                bookmark_load(buf, false);
                rc = GO_TO_FILEBROWSER;
                break;

            case FILE_ATTR_LNG:
                splash(0, ID2P(LANG_WAIT));
                if (lang_core_load(buf))
                {
                    splash(HZ, ID2P(LANG_FAILED));
                    break;
                }
                set_file(buf, (char *)global_settings.lang_file,
                        MAX_FILENAME);
                talk_init(); /* use voice of same language */
                viewportmanager_theme_changed(THEME_LANGUAGE);
                settings_apply_skins();
                splash(HZ, ID2P(LANG_LANGUAGE_LOADED));
                break;

#ifdef HAVE_LCD_BITMAP
            case FILE_ATTR_FONT:
                ft_load_font(buf);
                break;

            case FILE_ATTR_KBD:
                splash(0, ID2P(LANG_WAIT));
                if (!load_kbd(buf))
                    splash(HZ, ID2P(LANG_KEYBOARD_LOADED));
                set_file(buf, (char *)global_settings.kbd_file, MAX_FILENAME);
                break;
#endif

#if (CONFIG_PLATFORM & PLATFORM_NATIVE)
                /* firmware file */
            case FILE_ATTR_MOD:
                splash(0, ID2P(LANG_WAIT));
                audio_hard_stop();
                rolo_load(buf);
                break;
#endif

                /* plugin file */
            case FILE_ATTR_ROCK:
            case FILE_ATTR_LUA:
            {
                char *plugin = buf, *argument = NULL, lua_path[MAX_PATH];
                int ret;

                if ((file_attr & FILE_ATTR_MASK) == FILE_ATTR_LUA) {
                    snprintf(lua_path, sizeof(lua_path)-1, "%s/lua.rock", VIEWERS_DIR); /* Use a #define here ? */
                    plugin = lua_path;
                    argument = buf;
                }

                if (global_settings.party_mode && audio_status()) {
                    splash(HZ, ID2P(LANG_PARTY_MODE));
                    break;
                }
                ret = plugin_load(plugin, argument);
                switch (ret)
                {
                    case PLUGIN_GOTO_WPS:
                        play = true;
                        break;
                    case PLUGIN_USB_CONNECTED:
                        if(*c->dirfilter > NUM_FILTER_MODES)
                            /* leave sub-browsers after usb, doing
                               otherwise might be confusing to the user */
                            rc = GO_TO_ROOT;
                        else
                            rc = GO_TO_FILEBROWSER;
                        break;
                    /*
                    case PLUGIN_ERROR:
                    case PLUGIN_OK:
                    */
                    default:
                        break;
                }
                break;
            }
            case FILE_ATTR_CUE:
                display_cuesheet_content(buf);
                break;

            default:
            {
                const char* plugin;

                if (global_settings.party_mode && audio_status()) {
                    splash(HZ, ID2P(LANG_PARTY_MODE));
                    break;
                }

                struct entry* file = tree_get_entry_at(c, c->selected_item);
                plugin = filetype_get_plugin(file);
                if (plugin)
                {
                    switch (plugin_load(plugin,buf))
                    {
                        case PLUGIN_USB_CONNECTED:
                            rc = GO_TO_FILEBROWSER;
                            break;
                        case PLUGIN_GOTO_WPS:
                            rc = GO_TO_WPS;
                            break;
                        /*
                        case PLUGIN_OK:
                        case PLUGIN_ERROR:
                        */
                        default:
                            break;
                    }
                }
                break;
            }
        }

        if ( play ) {
            /* the resume_index must always be the index in the
               shuffled list in case shuffle is enabled */
            global_status.resume_index = start_index;
            global_status.resume_offset = 0;
            status_save();
            rc = GO_TO_WPS;
        }
        else {
            if (*c->dirfilter > NUM_FILTER_MODES &&
                *c->dirfilter != SHOW_CFG &&
                *c->dirfilter != SHOW_FONT &&
                *c->dirfilter != SHOW_PLUGINS)
            {
                rc = GO_TO_ROOT;
            }
        }
    }
    return rc;
}