libvlc_media_get_duration всегда возвращает 0 - PullRequest
2 голосов
/ 30 апреля 2011

Я пишу медиаплеер на чистом C и использую libvlc. В настоящее время я занимаюсь разработкой медиа-библиотеки и пишу каталогизатор и анализатор медиа-файлов. Он отлично работает с различными метаданными, такими как исполнители, альбомы и т. Д., Но libvlc_media_get_duration всегда возвращает 0. Я пробовал все и искал везде, но не могу заставить его работать. Кто-нибудь может мне помочь?

Вот код:

#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;
}

Спасибо!

Ответы [ 2 ]

7 голосов
/ 10 мая 2011

Если есть кто-то, кто хочет знать ответ и на этот вопрос, вот он:

Вам необходимо сыграть, чтобы узнать продолжительность.Жан-Батист Кемпф из Videolan Forums.

3 голосов
/ 18 мая 2011

Лучшим методом, вероятно, является вызов libvlc_media_parse() или его асинхронного аналога libvlc_media_parse_async().

После вызова libvlc_media_parse() ваших метаданных (включая продолжительность) будет подано.

...