void library_add_media(struct media_file_info *mfi) { if (!mfi->path || !mfi->fname) { DPRINTF(E_LOG, L_LIB, "Ignoring media file with missing values (path='%s', fname='%s', data_kind='%d')\n", mfi->path, mfi->fname, mfi->data_kind); return; } if (!mfi->directory_id || !mfi->virtual_path) { // Missing informations for virtual_path and directory_id (may) lead to misplaced appearance in mpd clients DPRINTF(E_WARN, L_LIB, "Media file with missing values (path='%s', directory='%d', virtual_path='%s')\n", mfi->path, mfi->directory_id, mfi->virtual_path); } if (!mfi->item_kind) mfi->item_kind = 2; /* music */ if (!mfi->media_kind) mfi->media_kind = MEDIA_KIND_MUSIC; /* music */ unicode_fixup_mfi(mfi); fixup_tags(mfi); if (mfi->id == 0) db_file_add(mfi); else db_file_update(mfi); }
static int process_track_file(plist_t trk) { struct media_file_info *mfi; char *location; char *path; char *string; uint64_t integer; char **strval; uint32_t *intval; char *chrval; uint8_t boolean; int mfi_id; int i; int ret; ret = get_dictval_string_from_key(trk, "Location", &location); if ((ret < 0) || !location) { DPRINTF(E_LOG, L_SCAN, "Track type File with no Location\n"); return -1; } if (strncmp(location, "file://", strlen("file://")) != 0) { DPRINTF(E_LOG, L_SCAN, "Track type File, but Location does not start with 'file://': '%s'\n", location); free(location); return -1; } path = evhttp_decode_uri(location + strlen("file://")); free(location); mfi_id = mfi_id_find(path); if (mfi_id <= 0) { free(path); return -1; } free(path); if (!cfg_getbool(cfg_getsec(cfg, "library"), "itunes_overrides")) return mfi_id; /* Override our metadata with what's provided by iTunes */ mfi = db_file_fetch_byid(mfi_id); if (!mfi) { DPRINTF(E_LOG, L_SCAN, "Could not retrieve file info for file id %d\n", mfi_id); return mfi_id; } for (i = 0; md_map[i].key != NULL; i++) { switch (md_map[i].type) { case PLIST_UINT: ret = get_dictval_int_from_key(trk, md_map[i].key, &integer); if (ret < 0) break; intval = (uint32_t *) ((char *) mfi + md_map[i].offset); *intval = (uint32_t)integer; break; case PLIST_STRING: ret = get_dictval_string_from_key(trk, md_map[i].key, &string); if (ret < 0) break; strval = (char **) ((char *) mfi + md_map[i].offset); if (*strval) free(*strval); *strval = string; break; case PLIST_BOOLEAN: ret = get_dictval_bool_from_key(trk, md_map[i].key, &boolean); if (ret < 0) break; chrval = (char *) mfi + md_map[i].offset; *chrval = boolean; break; case PLIST_DATE: intval = (uint32_t *) ((char *) mfi + md_map[i].offset); get_dictval_date_from_key(trk, md_map[i].key, intval); break; default: DPRINTF(E_WARN, L_SCAN, "Unhandled metadata type %d\n", md_map[i].type); break; } } /* Set media_kind to 4 (Podcast) if Podcast is true */ ret = get_dictval_bool_from_key(trk, "Podcast", &boolean); if ((ret == 0) && boolean) { mfi->media_kind = MEDIA_KIND_PODCAST; } /* Don't let album_artist set to "Unknown artist" if we've * filled artist from the iTunes data in the meantime */ if (strcmp(mfi->album_artist, "Unknown artist") == 0) { free(mfi->album_artist); mfi->album_artist = strdup(mfi->artist); } db_file_update(mfi); free_mfi(mfi, 0); return mfi_id; }
static void process_media_file(char *file, time_t mtime, off_t size, int compilation) { struct media_file_info mfi; char *filename; char *ext; time_t stamp; int id; int ret; db_file_stamp_bypath(file, &stamp, &id); if (stamp >= mtime) { db_file_ping(id); return; } memset(&mfi, 0, sizeof(struct media_file_info)); if (stamp) mfi.id = db_file_id_bypath(file); filename = strrchr(file, '/'); if (!filename) { DPRINTF(E_LOG, L_SCAN, "Could not determine filename for %s\n", file); return; } mfi.fname = strdup(filename + 1); if (!mfi.fname) { DPRINTF(E_WARN, L_SCAN, "Out of memory for fname\n"); return; } mfi.path = strdup(file); if (!mfi.path) { DPRINTF(E_WARN, L_SCAN, "Out of memory for path\n"); free(mfi.fname); return; } mfi.time_modified = mtime; mfi.file_size = size; ret = -1; /* Special cases */ ext = strrchr(file, '.'); if (ext) { if ((strcmp(ext, ".pls") == 0) || (strcmp(ext, ".url") == 0)) { mfi.data_kind = 1; /* url/stream */ ret = scan_url_file(file, &mfi); if (ret < 0) goto out; } else if ((strcmp(ext, ".png") == 0) || (strcmp(ext, ".jpg") == 0)) { /* Artwork - don't scan */ goto out; } } /* General case */ if (ret < 0) { ret = scan_metadata_ffmpeg(file, &mfi); mfi.data_kind = 0; /* real file */ } if (ret < 0) { DPRINTF(E_INFO, L_SCAN, "Could not extract metadata for %s\n", file); goto out; } mfi.compilation = compilation; if (!mfi.item_kind) mfi.item_kind = 2; /* music */ if (!mfi.media_kind) mfi.media_kind = 1; /* music */ unicode_fixup_mfi(&mfi); fixup_tags(&mfi); if (mfi.id == 0) db_file_add(&mfi); else db_file_update(&mfi); out: free_mfi(&mfi, 1); }
void filescanner_process_media(char *path, time_t mtime, off_t size, int type, struct media_file_info *external_mfi) { struct media_file_info *mfi; char *filename; time_t stamp; int id; int ret; filename = strrchr(path, '/'); if ((!filename) || (strlen(filename) == 1)) filename = path; else filename++; db_file_stamp_bypath(path, &stamp, &id); if (stamp && (stamp >= mtime)) { db_file_ping(id); return; } if (!external_mfi) { mfi = (struct media_file_info*)malloc(sizeof(struct media_file_info)); if (!mfi) { DPRINTF(E_LOG, L_SCAN, "Out of memory for mfi\n"); return; } memset(mfi, 0, sizeof(struct media_file_info)); } else mfi = external_mfi; if (stamp) mfi->id = db_file_id_bypath(path); mfi->fname = strdup(filename); if (!mfi->fname) { DPRINTF(E_LOG, L_SCAN, "Out of memory for fname\n"); goto out; } mfi->path = strdup(path); if (!mfi->path) { DPRINTF(E_LOG, L_SCAN, "Out of memory for path\n"); goto out; } mfi->time_modified = mtime; mfi->file_size = size; if (type & F_SCAN_TYPE_FILE) { mfi->data_kind = 0; /* real file */ ret = scan_metadata_ffmpeg(path, mfi); } else if (type & F_SCAN_TYPE_URL) { mfi->data_kind = 1; /* url/stream */ #if LIBAVFORMAT_VERSION_MAJOR >= 56 || (LIBAVFORMAT_VERSION_MAJOR == 55 && LIBAVFORMAT_VERSION_MINOR >= 13) ret = scan_metadata_ffmpeg(path, mfi); #else ret = scan_metadata_icy(path, mfi); #endif } else if (type & F_SCAN_TYPE_SPOTIFY) { mfi->data_kind = 2; /* iTunes has no spotify data kind, but we use 2 */ ret = mfi->artist && mfi->album && mfi->title; } else if (type & F_SCAN_TYPE_PIPE) { mfi->data_kind = 3; /* iTunes has no pipe data kind, but we use 3 */ mfi->type = strdup("wav"); mfi->codectype = strdup("wav"); mfi->description = strdup("PCM16 pipe"); ret = 1; } else { DPRINTF(E_LOG, L_SCAN, "Unknown scan type for %s, this error should not occur\n", path); ret = -1; } if (ret < 0) { DPRINTF(E_INFO, L_SCAN, "Could not extract metadata for %s\n", path); goto out; } if (type & F_SCAN_TYPE_COMPILATION) mfi->compilation = 1; if (type & F_SCAN_TYPE_PODCAST) mfi->media_kind = 4; /* podcast */ if (type & F_SCAN_TYPE_AUDIOBOOK) mfi->media_kind = 8; /* audiobook */ if (!mfi->item_kind) mfi->item_kind = 2; /* music */ if (!mfi->media_kind) mfi->media_kind = 1; /* music */ unicode_fixup_mfi(mfi); fixup_tags(mfi); if (mfi->id == 0) db_file_add(mfi); else db_file_update(mfi); out: if (!external_mfi) free_mfi(mfi, 0); }
void filescanner_process_media(char *path, time_t mtime, off_t size, int type, struct media_file_info *external_mfi, int dir_id) { struct media_file_info *mfi; char *filename; time_t stamp; int id; char virtual_path[PATH_MAX]; int ret; filename = strrchr(path, '/'); if ((!filename) || (strlen(filename) == 1)) filename = path; else filename++; db_file_stamp_bypath(path, &stamp, &id); if (stamp && (stamp >= mtime)) { db_file_ping(id); return; } if (!external_mfi) { mfi = (struct media_file_info*)malloc(sizeof(struct media_file_info)); if (!mfi) { DPRINTF(E_LOG, L_SCAN, "Out of memory for mfi\n"); return; } memset(mfi, 0, sizeof(struct media_file_info)); } else mfi = external_mfi; if (stamp) mfi->id = db_file_id_bypath(path); mfi->fname = strdup(filename); if (!mfi->fname) { DPRINTF(E_LOG, L_SCAN, "Out of memory for fname\n"); goto out; } mfi->path = strdup(path); if (!mfi->path) { DPRINTF(E_LOG, L_SCAN, "Out of memory for path\n"); goto out; } mfi->time_modified = mtime; mfi->file_size = size; if (type & F_SCAN_TYPE_COMPILATION) mfi->compilation = 1; if (type & F_SCAN_TYPE_PODCAST) mfi->media_kind = MEDIA_KIND_PODCAST; /* podcast */ if (type & F_SCAN_TYPE_AUDIOBOOK) mfi->media_kind = MEDIA_KIND_AUDIOBOOK; /* audiobook */ if (type & F_SCAN_TYPE_FILE) { mfi->data_kind = DATA_KIND_FILE; ret = scan_metadata_ffmpeg(path, mfi); } else if (type & F_SCAN_TYPE_URL) { mfi->data_kind = DATA_KIND_HTTP; ret = scan_metadata_ffmpeg(path, mfi); if (ret < 0) { DPRINTF(E_LOG, L_SCAN, "Playlist URL is unavailable for probe/metadata, assuming MP3 encoding\n"); mfi->type = strdup("mp3"); mfi->codectype = strdup("mpeg"); mfi->description = strdup("MPEG audio file"); ret = 1; } } else if (type & F_SCAN_TYPE_SPOTIFY) { mfi->data_kind = DATA_KIND_SPOTIFY; ret = mfi->artist && mfi->album && mfi->title; } else if (type & F_SCAN_TYPE_PIPE) { mfi->data_kind = DATA_KIND_PIPE; mfi->type = strdup("wav"); mfi->codectype = strdup("wav"); mfi->description = strdup("PCM16 pipe"); ret = 1; } else { DPRINTF(E_LOG, L_SCAN, "Unknown scan type for %s, this error should not occur\n", path); ret = -1; } if (ret < 0) { DPRINTF(E_INFO, L_SCAN, "Could not extract metadata for %s\n", path); goto out; } if (!mfi->item_kind) mfi->item_kind = 2; /* music */ if (!mfi->media_kind) mfi->media_kind = MEDIA_KIND_MUSIC; /* music */ unicode_fixup_mfi(mfi); fixup_tags(mfi); if (type & F_SCAN_TYPE_URL) { snprintf(virtual_path, PATH_MAX, "/http:/%s", mfi->title); mfi->virtual_path = strdup(virtual_path); } else if (type & F_SCAN_TYPE_SPOTIFY) { snprintf(virtual_path, PATH_MAX, "/spotify:/%s/%s/%s", mfi->album_artist, mfi->album, mfi->title); mfi->virtual_path = strdup(virtual_path); } else { snprintf(virtual_path, PATH_MAX, "/file:%s", mfi->path); mfi->virtual_path = strdup(virtual_path); } mfi->directory_id = dir_id; if (mfi->id == 0) db_file_add(mfi); else db_file_update(mfi); out: if (!external_mfi) free_mfi(mfi, 0); }