I'm writing a media player in pure C and I'm using libvlc. Currently I'm developing media library and i'm writing directory walker and media file parser. It works pretty fine with various metadata like artists or albums, etc., but libvlc_media_get_duration always returns 0. I tried everything and searched everywhere, but I can't make it work. Can anybody help me?
Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vlc/vlc.h>
#include <stdarg.h>
#include <stdbool.h>
#include <dirent.h>
#include <sys/stat.h>
void strcopy(char **dst, const char *src) {
unsigned int size = strlen(src);
*dst = (char *) realloc(*dst, sizeof(char) * (size + 1));
strncpy(*dst, src, size);
*(*dst+size) = 0;
}
void strconcat(char **dst, int n, ...) {
va_list args;
unsigned int count = 0;
// Count
va_start(args, n);
for (unsigned short i = 0; i < n; i++)
count += strlen(va_arg(args, char*));
va_end(args);
// Allocate
*dst = (char *) realloc(*dst, sizeof(char) * (count+1));
unsigned int cursor = 0;
va_start(args, n);
for(unsigned short i = 0; i < n; i++) {
char *src = va_arg(args, char*);
strncpy((*dst+cursor), src, strlen(src));
cursor += strlen(src);
*(*dst+cursor) = 0;
}
va_end(args);
}
void /* Process tags and add file to database */
__db_add_file(libvlc_instance_t *inst, const char *url, bool compute_hash) {
// Create new media
libvlc_media_t *media = libvlc_media_new_path(inst, url);
libvlc_media_parse(media);
if (libvlc_media_is_parsed(media)) {
printf("%s\n", url);
printf("%llu\n", libvlc_media_get_duration(media));
}
libvlc_media_release(media);
}
void /* Walker over directory */
__db_dir_walker(libvlc_instance_t *inst, const char *dir_url, bool compute_hash) {
// Build base path
char *base_url = NULL;
if (dir_url[strlen(dir_url)-1] != '/')
strconcat(&base_url, 2, dir_url, "/");
else
strcopy(&base_url, dir_url);
// Create necessary variables
struct dirent *entry;
DIR *dir;
struct stat fs;
// Try to open dir
if (!(dir = opendir(dir_url))) return;
while (entry = readdir(dir)) {
// Strip parent entries
if ((strcmp(".", entry->d_name) == 0) ||
(strcmp("..", entry->d_name) == 0)) continue;
char *dir_full_path = NULL;
strconcat(&dir_full_path, 2, base_url, entry->d_name);
if (stat(dir_full_path, &fs) < 0) return;
if (S_ISDIR(fs.st_mode)) { // Process directory
__db_dir_walker(inst, dir_full_path, compute_hash);
} else { // Process media file
__db_add_file(inst, dir_full_path, compute_hash);
}
}
// Free memory
closedir(dir);
}
void
db_scan_directory(const char *dir_url, bool compute_hash) {
// Try to open target dir
if (!opendir(dir_url)) return;
// Preload vlc instance for tag data retrieving
libvlc_instance_t *inst = libvlc_new(0, NULL);
// Walk over directory
__db_dir_walker(inst, dir_url, compute_hash);
// Free resources
libvlc_release(inst);
}
int main () {
db_scan_directory("/media/storage/music/Blur/", false);
return 0;
}
Thank you!
If there is anybody who wants to know answer on this question too, here it is:
You need to play to get the duration.
Thanks to Jean-Baptiste Kempf from Videolan Forums.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With