static void process_non_option(struct playlist *files, const char *arg) { glob_t gg; // Glob filenames on Windows (cmd.exe doesn't do this automatically) if (glob(arg, 0, NULL, &gg)) { playlist_add_file(files, arg); } else { for (int i = 0; i < gg.gl_pathc; i++) playlist_add_file(files, gg.gl_pathv[i]); globfree(&gg); } }
static int parse_dir(struct pl_parser *p) { if (p->real_stream->type != STREAMTYPE_DIR) return -1; if (p->probing) return 0; char *path = mp_file_get_path(p, bstr0(p->real_stream->url)); char **files = NULL; int num_files = 0; struct stat dir_stack[MAX_DIR_STACK]; scan_dir(p, path, dir_stack, 0, &files, &num_files); if (files) qsort(files, num_files, sizeof(files[0]), cmp_filename); for (int n = 0; n < num_files; n++) playlist_add_file(p->pl, files[n]); p->add_base = false; return num_files > 0 ? 0 : -1; }
static int parse_ref_init(struct pl_parser *p) { bstr line = bstr_strip(pl_get_line(p)); if (!bstr_equals0(line, "[Reference]")) return -1; // ASF http streaming redirection - this is needed because ffmpeg http:// // and mmsh:// can not automatically switch automatically between each // others. Both protocols use http - MMSH requires special http headers // to "activate" it, and will in other cases return this playlist. static const char *const mmsh_types[] = {"audio/x-ms-wax", "audio/x-ms-wma", "video/x-ms-asf", "video/x-ms-afs", "video/x-ms-wmv", "video/x-ms-wma", "application/x-mms-framed", "application/vnd.ms.wms-hdr.asfv1", NULL}; bstr burl = bstr0(p->s->url); if (bstr_eatstart0(&burl, "http://") && check_mimetype(p->s, mmsh_types)) { MP_INFO(p, "Redirecting to mmsh://\n"); playlist_add_file(p->pl, talloc_asprintf(p, "mmsh://%.*s", BSTR_P(burl))); return 0; } while (!pl_eof(p)) { line = bstr_strip(pl_get_line(p)); if (bstr_case_startswith(line, bstr0("Ref"))) { bstr_split_tok(line, "=", &(bstr){0}, &line); if (line.len) pl_add(p, line); } } return 0; }
static void asx_parse_ref(ASX_Parser_t* parser, char** attribs) { char *href; href = asx_get_attrib("HREF",attribs); if(href == NULL) { asx_warning_attrib_required(parser,"REF" ,"HREF" ); return; } #if 0 // replace http my mmshttp to avoid infinite loops // disabled since some playlists for e.g. WinAMP use asx as well // "-user-agent NSPlayer/4.1.0.3856" is a possible workaround if (strncmp(href, "http://", 7) == 0) { char *newref = malloc(3 + strlen(href) + 1); strcpy(newref, "mms"); strcpy(newref + 3, href); free(href); href = newref; } #endif playlist_add_file(parser->pl, href); mp_msg(MSGT_PLAYTREE,MSGL_V,"Adding file %s to element entry\n",href); free(href); }
MusicPlayer::MusicPlayer(QWidget *parent) : QWidget(parent), m_ui(new Ui::MusicPlayer), m_query(new QSqlQuery) { m_ui->setupUi(this); mediaObject = new Phonon::MediaObject(this); audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this); Phonon::createPath(mediaObject, audioOutput); mediaObject->setTickInterval(1000); connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64))); connect(mediaObject, SIGNAL(aboutToFinish()), this, SLOT(enqueueNextSource())); dlgAddMusic = new AddMusic ( this ); connect ( dlgAddMusic, SIGNAL(selected_artistid(quint64)), this, SLOT(playlist_add_artistid(quint64))); connect ( dlgAddMusic, SIGNAL(selected_albumid(quint64)), this, SLOT(playlist_add_albumid(quint64))); connect ( dlgAddMusic, SIGNAL(selected_songid(quint64)), this, SLOT(playlist_add_songid(quint64))); connect ( dlgAddMusic, SIGNAL(selected_file(QString)), this, SLOT(playlist_add_file(QString))); }
static int open_file(struct demuxer *demuxer, enum demux_check check) { if (stream_get_size(demuxer->stream) == 0) return -1; int flags = 0; if (check <= DEMUX_CHECK_REQUEST) flags |= MP_ARCHIVE_FLAG_UNSAFE; struct mp_archive *mpa = mp_archive_new(demuxer->log, demuxer->stream, flags); if (!mpa) return -1; struct playlist *pl = talloc_zero(demuxer, struct playlist); demuxer->playlist = pl; // make it load archive:// pl->disable_safety = true; char *prefix = mp_url_escape(mpa, demuxer->stream->url, "~|"); char **files = NULL; int num_files = 0; for (;;) { struct archive_entry *entry; int r = archive_read_next_header(mpa->arch, &entry); if (r == ARCHIVE_EOF) break; if (r < ARCHIVE_OK) MP_ERR(demuxer, "libarchive: %s\n", archive_error_string(mpa->arch)); if (r < ARCHIVE_WARN) break; if (archive_entry_filetype(entry) != AE_IFREG) continue; const char *fn = archive_entry_pathname(entry); // Some archives may have no filenames. if (!fn) fn = talloc_asprintf(mpa, "mpv_unknown#%d\n", num_files); // stream_libarchive.c does the real work char *f = talloc_asprintf(mpa, "archive://%s|%s", prefix, fn); MP_TARRAY_APPEND(mpa, files, num_files, f); } if (files) qsort(files, num_files, sizeof(files[0]), cmp_filename); for (int n = 0; n < num_files; n++) playlist_add_file(pl, files[n]); demuxer->filetype = "archive"; demuxer->fully_read = true; mp_archive_free(mpa); return 0; }
void on_add_file_activate(GtkAction * action, gpointer user_data) { GtkWidget *dialog; GtkResponseType response; gchar last_dir[PATH_MAX]; GSList *filenames; gchar *filename; g_strlcpy(last_dir, prefs.last_dir, sizeof(last_dir)); dialog = gtk_file_chooser_dialog_new(_("Add Files"), get_window(app), GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_ADD, 1, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE); gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), last_dir); gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400); gtk_widget_show_all(dialog); while((response = gtk_dialog_run(GTK_DIALOG(dialog))) == 1) { filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)); while(filenames) { filename = (gchar*)filenames->data; if (filename) { playlist_add_file(get_playlist(app), filename, TRUE); g_free(filename); } filenames = g_slist_next(filenames); } g_slist_free(filenames); playlist_write(get_playlist(app)); } gtk_widget_destroy(dialog); }
void merge_playlist_files(struct playlist *pl) { if (!pl->first) return; char *edl = talloc_strdup(NULL, "edl://"); for (struct playlist_entry *e = pl->first; e; e = e->next) { if (e != pl->first) edl = talloc_strdup_append_buffer(edl, ";"); // Escape if needed if (e->filename[strcspn(e->filename, "=%,;\n")] || bstr_strip(bstr0(e->filename)).len != strlen(e->filename)) { // %length% edl = talloc_asprintf_append_buffer(edl, "%%%zd%%", strlen(e->filename)); } edl = talloc_strdup_append_buffer(edl, e->filename); } playlist_clear(pl); playlist_add_file(pl, edl); talloc_free(edl); }
static int parse_dir(struct pl_parser *p) { if (p->real_stream->type != STREAMTYPE_DIR) return -1; if (p->probing) return 0; char *path = mp_file_get_path(p, bstr0(p->real_stream->url)); if (strlen(path) >= 8192) return -1; // things like mount bind loops DIR *dp = opendir(path); if (!dp) { MP_ERR(p, "Could not read directory.\n"); return -1; } char **files = NULL; int num_files = 0; struct dirent *ep; while ((ep = readdir(dp))) { if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) continue; MP_TARRAY_APPEND(p, files, num_files, talloc_strdup(p, ep->d_name)); } if (files) qsort(files, num_files, sizeof(files[0]), cmp_filename); for (int n = 0; n < num_files; n++) playlist_add_file(p->pl, mp_path_join(p, path, files[n])); closedir(dp); p->add_base = false; return num_files > 0 ? 0 : -1; }
static int open_file(struct demuxer *demuxer, enum demux_check check) { if (!demuxer->access_references) return -1; if (RarProbe(demuxer->stream)) return -1; int count; rar_file_t **files; if (RarParse(demuxer->stream, &count, &files)) return -1; void *tmp = talloc_new(NULL); talloc_steal(tmp, files); struct playlist *pl = talloc_zero(demuxer, struct playlist); demuxer->playlist = pl; // make it load rar:// pl->disable_safety = true; char *prefix = mp_url_escape(tmp, demuxer->stream->url, "~|"); for (int n = 0; n < count; n++) { // stream_rar.c does the real work playlist_add_file(pl, talloc_asprintf(tmp, "rar://%s|%s", prefix, files[n]->name)); RarFileDelete(files[n]); } demuxer->filetype = "rar"; demuxer->fully_read = true; talloc_free(tmp); return 0; }
static void pl_add(struct pl_parser *p, bstr entry) { char *s = bstrto0(NULL, entry); playlist_add_file(p->pl, s); talloc_free(s); }
static void process_non_option(struct playlist *files, const char *arg) { playlist_add_file(files, arg); }
void update_vo_playback_state(struct MPContext *mpctx) { if (mpctx->video_out && mpctx->video_out->config_ok) { struct voctrl_playback_state oldstate = mpctx->vo_playback_state; struct voctrl_playback_state newstate = { .taskbar_progress = mpctx->opts->vo->taskbar_progress, .playing = mpctx->playing, .paused = mpctx->paused, .percent_pos = get_percent_pos(mpctx), }; if (oldstate.taskbar_progress != newstate.taskbar_progress || oldstate.playing != newstate.playing || oldstate.paused != newstate.paused || oldstate.percent_pos != newstate.percent_pos) { // Don't update progress bar if it was and still is hidden if ((oldstate.playing && oldstate.taskbar_progress) || (newstate.playing && newstate.taskbar_progress)) { vo_control_async(mpctx->video_out, VOCTRL_UPDATE_PLAYBACK_STATE, &newstate); } mpctx->vo_playback_state = newstate; } } else { mpctx->vo_playback_state = (struct voctrl_playback_state){ 0 }; } } void update_window_title(struct MPContext *mpctx, bool force) { if (!mpctx->video_out && !mpctx->ao) { talloc_free(mpctx->last_window_title); mpctx->last_window_title = NULL; return; } char *title = mp_property_expand_string(mpctx, mpctx->opts->wintitle); if (!mpctx->last_window_title || force || strcmp(title, mpctx->last_window_title) != 0) { talloc_free(mpctx->last_window_title); mpctx->last_window_title = talloc_steal(mpctx, title); if (mpctx->video_out) vo_control(mpctx->video_out, VOCTRL_UPDATE_WINDOW_TITLE, title); if (mpctx->ao) { ao_control(mpctx->ao, AOCONTROL_UPDATE_STREAM_TITLE, title); } } else { talloc_free(title); } } void error_on_track(struct MPContext *mpctx, struct track *track) { if (!track || !track->selected) return; mp_deselect_track(mpctx, track); if (track->type == STREAM_AUDIO) MP_INFO(mpctx, "Audio: no audio\n"); if (track->type == STREAM_VIDEO) MP_INFO(mpctx, "Video: no video\n"); if (mpctx->opts->stop_playback_on_init_failure || !(mpctx->vo_chain || mpctx->ao_chain)) { if (!mpctx->stop_play) mpctx->stop_play = PT_ERROR; if (mpctx->error_playing >= 0) mpctx->error_playing = MPV_ERROR_NOTHING_TO_PLAY; } mp_wakeup_core(mpctx); } int stream_dump(struct MPContext *mpctx, const char *source_filename) { struct MPOpts *opts = mpctx->opts; stream_t *stream = stream_open(source_filename, mpctx->global); if (!stream) return -1; int64_t size = stream_get_size(stream); FILE *dest = fopen(opts->stream_dump, "wb"); if (!dest) { MP_ERR(mpctx, "Error opening dump file: %s\n", mp_strerror(errno)); return -1; } bool ok = true; while (mpctx->stop_play == KEEP_PLAYING && ok) { if (!opts->quiet && ((stream->pos / (1024 * 1024)) % 2) == 1) { uint64_t pos = stream->pos; MP_MSG(mpctx, MSGL_STATUS, "Dumping %lld/%lld...", (long long int)pos, (long long int)size); } bstr data = stream_peek(stream, STREAM_MAX_BUFFER_SIZE); if (data.len == 0) { ok &= stream->eof; break; } ok &= fwrite(data.start, data.len, 1, dest) == 1; stream_skip(stream, data.len); mp_wakeup_core(mpctx); // don't actually sleep mp_idle(mpctx); // but process input } ok &= fclose(dest) == 0; free_stream(stream); return ok ? 0 : -1; } void merge_playlist_files(struct playlist *pl) { if (!pl->first) return; char *edl = talloc_strdup(NULL, "edl://"); for (struct playlist_entry *e = pl->first; e; e = e->next) { if (e != pl->first) edl = talloc_strdup_append_buffer(edl, ";"); // Escape if needed if (e->filename[strcspn(e->filename, "=%,;\n")] || bstr_strip(bstr0(e->filename)).len != strlen(e->filename)) { // %length% edl = talloc_asprintf_append_buffer(edl, "%%%zd%%", strlen(e->filename)); } edl = talloc_strdup_append_buffer(edl, e->filename); } playlist_clear(pl); playlist_add_file(pl, edl); talloc_free(edl); }