Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  downloader.c   Sprache: C

 

/*****************************************************************************
 * downloader.c:  libvlc downloader API sample usage
 *****************************************************************************
 * Copyright (C) 2026 VLC authors and VideoLAN
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/


/*
 * Program usage:
 *   Usage: <total number of media to download> <MRLtodownload1> [MRLtodownload2]...
 *
 * Example:
 *   ./doc/samples_libvlc_downloader 2 https://example.org/a.mp4 file:///home/user/b.mp3
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>
#include <semaphore.h>
#include <inttypes.h>

#include <vlc/vlc.h>
#include <vlc/libvlc_downloader.h>

struct request_ctx
{
    int index;
    sem_t *done_sem;
};

static const char *dl_status_to_string(libvlc_downloader_status_t st)
{
    switch (st)
    {
        case libvlc_downloader_status_pending:   return "pending";
        case libvlc_downloader_status_running:   return "running";
        case libvlc_downloader_status_paused:    return "paused";
        case libvlc_downloader_status_finished:  return "finished";
        case libvlc_downloader_status_cancelled: return "cancelled";
        case libvlc_downloader_status_error:     return "error";
        default: return "unknown";
    }
}

static ptrdiff_t on_buffer(void *opaque, libvlc_downloader_task *task, const uint8_t *buf,
                           size_t len, uint64_t position, uint64_t total)
{
    (void)buf;
    struct request_ctx *ctx = (struct request_ctx *)opaque;
    /* Buffer received for media. User can process or save 'buf' here. */
    fprintf(stdout, "[req %d] received buffer: %zu bytes\n", ctx->index, len);
    double pct = (total > 0) ? (100.0 * (double)position / (double)total) : 0.0;
    fprintf(stdout, "[req %d, id=%p] progress: %" PRIu64 "/%" PRIu64 " (%.1f%%)\n",
            ctx->index, task, position, total, pct);
    fflush(stdout);
    return (ptrdiff_t)len;
}

static void on_state_update(void *opaque, libvlc_downloader_task *task,
                            libvlc_downloader_status_t status)
{
    struct request_ctx *ctx = (struct request_ctx *)opaque;
    fprintf(stdout, "[req %d, id=%p] state: %s\n",
            ctx->index, task, dl_status_to_string(status));
    fflush(stdout);

    if (status == libvlc_downloader_status_finished ||
        status == libvlc_downloader_status_cancelled ||
        status == libvlc_downloader_status_error)
    {
        sem_post(ctx->done_sem);
    }
}

static void on_subitems(void *opaque, libvlc_downloader_task *task, libvlc_media_list_t *subitems)
{
    (void)task;
    struct request_ctx *ctx = (struct request_ctx *)opaque;
    int count = libvlc_media_list_count(subitems);
    fprintf(stdout, "[req %d] media has %d subitems (download will not proceed for playlists/directories)\n",
            ctx->index, count);
    fflush(stdout);
}

static void on_slaves(void *opaque, libvlc_downloader_task *task, libvlc_media_slave_t **slaves, size_t count)
{
    (void)task;
    struct request_ctx *ctx = (struct request_ctx *)opaque;
    fprintf(stdout, "[req %d] media has %zu slave(s)\n", ctx->index, count);
    (void)slaves;
    fflush(stdout);
}

static libvlc_downloader_t *create_downloader(const struct libvlc_downloader_cfg *cfg)
{
    static const char* const argv[] = {
        "-vvv",
        "--vout=dummy",
        "--aout=dummy",
        "--text-renderer=dummy",
    };
    libvlc_instance_t *inst = libvlc_new((int)(sizeof argv / sizeof *argv), argv);
    if (inst == NULL)
        return NULL;

    libvlc_downloader_t *downloader = libvlc_downloader_new(inst, cfg);
    /* downloader retains the instance, we can release our reference */
    libvlc_release(inst);
    return downloader;
}

static void print_usage(const char *name)
{
    fprintf(stderr,
            "Usage: %s <total number of media to download> <mediatodownload1> [mediatodownload2]...\n",
            name);
}

int main(int argc, const char **argv)
{
    setlocale(LC_ALL, "");

    if (argc < 2)
    {
        print_usage(argv[0]);
        return EXIT_FAILURE;
    }

    char *endp = NULL;
    long nlong = strtol(argv[1], &endp, 10);
    if (endp == argv[1] || nlong <= 0)
    {
        print_usage(argv[0]);
        return EXIT_FAILURE;
    }
    int total = (int)nlong;

    /* expect: prog N media1 ... mediaN */
    if (argc != 2 + total)
    {
        print_usage(argv[0]);
        return EXIT_FAILURE;
    }

    const char **media_uris = &argv[2];

    const struct libvlc_downloader_cfg cfg = {
        .version = 0,
        .max_parser_threads = 1,
    };
    libvlc_downloader_t *downloader = create_downloader(&cfg);
    if (downloader == NULL)
    {
        fprintf(stderr, "Failed to create downloader\n");
        return EXIT_FAILURE;
    }

    static const struct libvlc_downloader_cbs cbs = {
        .version = 0,
        .on_state_update = on_state_update,
        .on_buffer = on_buffer,
        .on_subitems = on_subitems,
        .on_slaves = on_slaves,
    };

    sem_t done_sem;
    sem_init(&done_sem, 0, 0);

    struct request_ctx *ctxs = calloc((size_t)total, sizeof(*ctxs));
    if (ctxs == NULL)
    {
        fprintf(stderr, "Failed to create context\n");
        libvlc_downloader_destroy(downloader);
        sem_destroy(&done_sem);
        return EXIT_FAILURE;
    }

    int queued = 0;

    for (int i = 0; i < total; ++i)
    {
        const char *url = media_uris[i];
        libvlc_media_t *media = NULL;
        if (strstr(url, "://") != NULL)
            media = libvlc_media_new_location(url);
        else
            media = libvlc_media_new_path(url);

        if (media == NULL)
        {
            fprintf(stderr, "[req %d] failed to create media for '%s'\n", i, url);
            continue;
        }

        ctxs[i].index = i;
        ctxs[i].done_sem = &done_sem;

        const libvlc_downloader_request_t req = {
            .version = 0,
            .media = media,
        };

        libvlc_downloader_task *task = libvlc_downloader_task_new(downloader, &req, &cbs, &ctxs[i]);

        libvlc_media_release(media);

        if (task == NULL)
            continue;

        if (libvlc_downloader_submit(downloader, task) == 0)
        {
            fprintf(stdout, "[req %d, id=%p] queued: %s\n",
                    i, task, url);
            fflush(stdout);
            queued++;
        }
        else
            fprintf(stderr, "[req %d] failed to queue download for '%s'\n", i, url);

        /* Task isn't used anymore by the caller, so drop the reference right away. */
        libvlc_downloader_task_release(task);
    }

    for (int i = 0; i < queued; ++i)
        sem_wait(&done_sem);

    fprintf(stdout, "All %d queued download(s) completed (finished/cancelled/error).\n", queued);
    fflush(stdout);

    libvlc_downloader_destroy(downloader);
    sem_destroy(&done_sem);
    free(ctxs);

    return queued > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

Messung
CHZG
919410094

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104845
#Domains=499266