Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

libvlc_media_get_duration always returns 0

Tags:

c

libvlc

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!

like image 777
dancingrobot84 Avatar asked Dec 08 '25 10:12

dancingrobot84


1 Answers

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.

like image 197
dancingrobot84 Avatar answered Dec 10 '25 09:12

dancingrobot84