Recherche avancée

Médias (1)

Mot : - Tags -/blender

Autres articles (53)

  • Modifier la date de publication

    21 juin 2013, par

    Comment changer la date de publication d’un média ?
    Il faut au préalable rajouter un champ "Date de publication" dans le masque de formulaire adéquat :
    Administrer > Configuration des masques de formulaires > Sélectionner "Un média"
    Dans la rubrique "Champs à ajouter, cocher "Date de publication "
    Cliquer en bas de la page sur Enregistrer

  • Les autorisations surchargées par les plugins

    27 avril 2010, par

    Mediaspip core
    autoriser_auteur_modifier() afin que les visiteurs soient capables de modifier leurs informations sur la page d’auteurs

  • Encoding and processing into web-friendly formats

    13 avril 2011, par

    MediaSPIP automatically converts uploaded files to internet-compatible formats.
    Video files are encoded in MP4, Ogv and WebM (supported by HTML5) and MP4 (supported by Flash).
    Audio files are encoded in MP3 and Ogg (supported by HTML5) and MP3 (supported by Flash).
    Where possible, text is analyzed in order to retrieve the data needed for search engine detection, and then exported as a series of image files.
    All uploaded files are stored online in their original format, so you can (...)

Sur d’autres sites (5699)

  • Saving frames as JPG with FFMPEG (Visual Studio / C++)

    10 novembre 2022, par Diego Satizabal

    I am trying to save all frames from a mp4 video in separate JPG files, I have a code that runs and actually saves something to JPG files but files are not recognized as images and nothing is showing.

    


    Below my full code, I am using Visual Studio 2022 in Windows 11 and FFMPEG 5.1. The function that saves the images is save_frame_as_jpeg which is actually an adaption from the code provided here but changing the use of avcodec_encode_video2 for avcodec_send_frame/avcodec_receive_packet as indicated in the documentation.

    


    I am obiously doing something wrong but cannot quite find it, BTW, I know that a simple command (ffmpeg -i input.mp4 -vf fps=1 vid_%d.png) will do this but I am requiring to do it by code.

    


    Any help is appreciated, thanks in advance !

    


        // FfmpegTests.cpp : This file contains the &#x27;main&#x27; function. Program execution begins and ends there.&#xA;//&#xA;#pragma warning(disable : 4996)&#xA;extern "C"&#xA;{&#xA;    #include "libavformat/avformat.h"&#xA;    #include "libavcodec/avcodec.h"&#xA;    #include "libavfilter/avfilter.h"&#xA;    #include "libavutil/opt.h"&#xA;    #include "libavutil/avutil.h"&#xA;    #include "libavutil/error.h"&#xA;    #include "libavfilter/buffersrc.h"&#xA;    #include "libavfilter/buffersink.h"&#xA;    #include "libswscale/swscale.h"&#xA;}&#xA;&#xA;#pragma comment(lib, "avcodec.lib")&#xA;#pragma comment(lib, "avformat.lib")&#xA;#pragma comment(lib, "avfilter.lib")&#xA;#pragma comment(lib, "avutil.lib")&#xA;#pragma comment(lib, "swscale.lib")&#xA;&#xA;#include <cstdio>&#xA;#include <iostream>&#xA;#include <chrono>&#xA;#include <thread>&#xA;&#xA;&#xA;static AVFormatContext* fmt_ctx;&#xA;static AVCodecContext* dec_ctx;&#xA;AVFilterGraph* filter_graph;&#xA;AVFilterContext* buffersrc_ctx;&#xA;AVFilterContext* buffersink_ctx;&#xA;static int video_stream_index = -1;&#xA;&#xA;const char* filter_descr = "scale=78:24,transpose=cclock";&#xA;static int64_t last_pts = AV_NOPTS_VALUE;&#xA;&#xA;static int open_input_file(const char* filename)&#xA;{&#xA;    const AVCodec* dec;&#xA;    int ret;&#xA;&#xA;    if ((ret = avformat_open_input(&amp;fmt_ctx, filename, NULL, NULL)) &lt; 0) {&#xA;        av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");&#xA;        return ret;&#xA;    }&#xA;&#xA;    if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) &lt; 0) {&#xA;        av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");&#xA;        return ret;&#xA;    }&#xA;&#xA;    /* select the video stream */&#xA;    ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &amp;dec, 0);&#xA;    if (ret &lt; 0) {&#xA;        av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n");&#xA;        return ret;&#xA;    }&#xA;    video_stream_index = ret;&#xA;&#xA;    /* create decoding context */&#xA;    dec_ctx = avcodec_alloc_context3(dec);&#xA;    if (!dec_ctx)&#xA;        return AVERROR(ENOMEM);&#xA;    avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);&#xA;&#xA;    /* init the video decoder */&#xA;    if ((ret = avcodec_open2(dec_ctx, dec, NULL)) &lt; 0) {&#xA;        av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n");&#xA;        return ret;&#xA;    }&#xA;&#xA;    return 0;&#xA;}&#xA;&#xA;static int init_filters(const char* filters_descr)&#xA;{&#xA;    char args[512];&#xA;    int ret = 0;&#xA;    const AVFilter* buffersrc = avfilter_get_by_name("buffer");&#xA;    const AVFilter* buffersink = avfilter_get_by_name("buffersink");&#xA;    AVFilterInOut* outputs = avfilter_inout_alloc();&#xA;    AVFilterInOut* inputs = avfilter_inout_alloc();&#xA;    AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;&#xA;    enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE };&#xA;&#xA;    filter_graph = avfilter_graph_alloc();&#xA;    if (!outputs || !inputs || !filter_graph) {&#xA;        ret = AVERROR(ENOMEM);&#xA;        goto end;&#xA;    }&#xA;&#xA;    /* buffer video source: the decoded frames from the decoder will be inserted here. */&#xA;    snprintf(args, sizeof(args),&#xA;        "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",&#xA;        dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,&#xA;        time_base.num, time_base.den,&#xA;        dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);&#xA;&#xA;    ret = avfilter_graph_create_filter(&amp;buffersrc_ctx, buffersrc, "in",&#xA;        args, NULL, filter_graph);&#xA;    if (ret &lt; 0) {&#xA;        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");&#xA;        goto end;&#xA;    }&#xA;&#xA;    /* buffer video sink: to terminate the filter chain. */&#xA;    ret = avfilter_graph_create_filter(&amp;buffersink_ctx, buffersink, "out",&#xA;        NULL, NULL, filter_graph);&#xA;    if (ret &lt; 0) {&#xA;        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");&#xA;        goto end;&#xA;    }&#xA;&#xA;    ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);&#xA;    if (ret &lt; 0) {&#xA;        av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");&#xA;        goto end;&#xA;    }&#xA;&#xA;    outputs->name = av_strdup("in");&#xA;    outputs->filter_ctx = buffersrc_ctx;&#xA;    outputs->pad_idx = 0;&#xA;    outputs->next = NULL;&#xA;&#xA;    inputs->name = av_strdup("out");&#xA;    inputs->filter_ctx = buffersink_ctx;&#xA;    inputs->pad_idx = 0;&#xA;    inputs->next = NULL;&#xA;&#xA;    if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,&#xA;        &amp;inputs, &amp;outputs, NULL)) &lt; 0)&#xA;        goto end;&#xA;&#xA;    if ((ret = avfilter_graph_config(filter_graph, NULL)) &lt; 0)&#xA;        goto end;&#xA;&#xA;end:&#xA;    avfilter_inout_free(&amp;inputs);&#xA;    avfilter_inout_free(&amp;outputs);&#xA;&#xA;    return ret;&#xA;}&#xA;&#xA;static void display_frame(const AVFrame* frame, AVRational time_base)&#xA;{&#xA;    int x, y;&#xA;    uint8_t* p0, * p;&#xA;    int64_t delay;&#xA;&#xA;    if (frame->pts != AV_NOPTS_VALUE) {&#xA;        if (last_pts != AV_NOPTS_VALUE) {&#xA;            /* sleep roughly the right amount of time;&#xA;             * usleep is in microseconds, just like AV_TIME_BASE. */&#xA;            AVRational timeBaseQ;&#xA;            timeBaseQ.num = 1;&#xA;            timeBaseQ.den = AV_TIME_BASE;&#xA;&#xA;            delay = av_rescale_q(frame->pts - last_pts, time_base, timeBaseQ);&#xA;            if (delay > 0 &amp;&amp; delay &lt; 1000000)&#xA;                std::this_thread::sleep_for(std::chrono::microseconds(delay));&#xA;        }&#xA;        last_pts = frame->pts;&#xA;    }&#xA;&#xA;    /* Trivial ASCII grayscale display. */&#xA;    p0 = frame->data[0];&#xA;    puts("\033c");&#xA;    for (y = 0; y &lt; frame->height; y&#x2B;&#x2B;) {&#xA;        p = p0;&#xA;        for (x = 0; x &lt; frame->width; x&#x2B;&#x2B;)&#xA;            putchar(" .-&#x2B;#"[*(p&#x2B;&#x2B;) / 52]);&#xA;        putchar(&#x27;\n&#x27;);&#xA;        p0 &#x2B;= frame->linesize[0];&#xA;    }&#xA;    fflush(stdout);&#xA;}&#xA;&#xA;int save_frame_as_jpeg(AVCodecContext* pCodecCtx, AVFrame* pFrame, int FrameNo) {&#xA;    int ret = 0;&#xA;&#xA;    const AVCodec* jpegCodec = avcodec_find_encoder(AV_CODEC_ID_JPEG2000);&#xA;    if (!jpegCodec) {&#xA;        return -1;&#xA;    }&#xA;    AVCodecContext* jpegContext = avcodec_alloc_context3(jpegCodec);&#xA;    if (!jpegContext) {&#xA;        return -1;&#xA;    }&#xA;&#xA;    jpegContext->pix_fmt = pCodecCtx->pix_fmt;&#xA;    jpegContext->height = pFrame->height;&#xA;    jpegContext->width = pFrame->width;&#xA;    jpegContext->time_base = AVRational{ 1,10 };&#xA;&#xA;    ret = avcodec_open2(jpegContext, jpegCodec, NULL);&#xA;    if (ret &lt; 0) {&#xA;        return ret;&#xA;    }&#xA;    FILE* JPEGFile;&#xA;    char JPEGFName[256];&#xA;&#xA;    AVPacket packet;&#xA;    packet.data = NULL;&#xA;    packet.size = 0;&#xA;    av_init_packet(&amp;packet);&#xA;&#xA;    int gotFrame;&#xA;&#xA;    ret = avcodec_send_frame(jpegContext, pFrame);&#xA;    if (ret &lt; 0) {&#xA;        return ret;&#xA;    }&#xA;&#xA;    ret = avcodec_receive_packet(jpegContext, &amp;packet);&#xA;    if (ret &lt; 0) {&#xA;        return ret;&#xA;    }&#xA;&#xA;    sprintf(JPEGFName, "c:\\folder\\dvr-%06d.jpg", FrameNo);&#xA;    JPEGFile = fopen(JPEGFName, "wb");&#xA;    fwrite(packet.data, 1, packet.size, JPEGFile);&#xA;    fclose(JPEGFile);&#xA;&#xA;    av_packet_unref(&amp;packet);&#xA;    avcodec_close(jpegContext);&#xA;    return 0;&#xA;}&#xA;&#xA;int main(int argc, char** argv)&#xA;{&#xA;    AVFrame* frame;&#xA;    AVFrame* filt_frame;&#xA;    AVPacket* packet;&#xA;    int ret;&#xA;&#xA;    if (argc != 2) {&#xA;        fprintf(stderr, "Usage: %s file\n", argv[0]);&#xA;        exit(1);&#xA;    }&#xA;&#xA;    frame = av_frame_alloc();&#xA;    filt_frame = av_frame_alloc();&#xA;    packet = av_packet_alloc();&#xA;&#xA;    if (!frame || !filt_frame || !packet) {&#xA;        fprintf(stderr, "Could not allocate frame or packet\n");&#xA;        exit(1);&#xA;    }&#xA;&#xA;    if ((ret = open_input_file(argv[1])) &lt; 0)&#xA;        goto end;&#xA;    if ((ret = init_filters(filter_descr)) &lt; 0)&#xA;        goto end;&#xA;&#xA;    while (true)&#xA;    {&#xA;        if ((ret = av_read_frame(fmt_ctx, packet)) &lt; 0)&#xA;            break;&#xA;&#xA;        if (packet->stream_index == video_stream_index) {&#xA;            ret = avcodec_send_packet(dec_ctx, packet);&#xA;            if (ret &lt; 0) {&#xA;                av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");&#xA;                break;&#xA;            }&#xA;&#xA;            while (ret >= 0)&#xA;            {&#xA;                ret = avcodec_receive_frame(dec_ctx, frame);&#xA;                if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {&#xA;                    break;&#xA;                }&#xA;                else if (ret &lt; 0) {&#xA;                    av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");&#xA;                    goto end;&#xA;                }&#xA;&#xA;                frame->pts = frame->best_effort_timestamp;&#xA;&#xA;                /* push the decoded frame into the filtergraph */&#xA;                if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) &lt; 0) {&#xA;                    av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");&#xA;                    break;&#xA;                }&#xA;&#xA;                /* pull filtered frames from the filtergraph */&#xA;                while (1) {&#xA;                    ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);&#xA;                    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)&#xA;                        break;&#xA;                    if (ret &lt; 0)&#xA;                        goto end;&#xA;                    display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);&#xA;                    av_frame_unref(filt_frame);&#xA;                    &#xA;                    ret = save_frame_as_jpeg(dec_ctx, frame, dec_ctx->frame_number);&#xA;                    if (ret &lt; 0)&#xA;                        goto end;&#xA;                }&#xA;                av_frame_unref(frame);&#xA;            }&#xA;        }&#xA;        av_packet_unref(packet);&#xA;    }&#xA;&#xA;end:&#xA;    avfilter_graph_free(&amp;filter_graph);&#xA;    avcodec_free_context(&amp;dec_ctx);&#xA;    avformat_close_input(&amp;fmt_ctx);&#xA;    av_frame_free(&amp;frame);&#xA;    av_frame_free(&amp;filt_frame);&#xA;    av_packet_free(&amp;packet);&#xA;&#xA;    if (ret &lt; 0 &amp;&amp; ret != AVERROR_EOF) {&#xA;        char errBuf[AV_ERROR_MAX_STRING_SIZE]{0};&#xA;        int res = av_strerror(ret, errBuf, AV_ERROR_MAX_STRING_SIZE);&#xA;        fprintf(stderr, "Error:  %s\n", errBuf);&#xA;        exit(1);&#xA;    }&#xA;&#xA;    exit(0);&#xA;}&#xA;</thread></chrono></iostream></cstdio>

    &#xA;

  • ffmpeg encoding leaves me with blank space at the end where the video pauses and there is nothing ahead

    6 novembre 2022, par Nisarg Desai

    I was trying to slice some of the video being played and clip it in mpv.net using a .lua script which uses ffmpeg to encode the webm output. ffmpeg sometimes leaves some seconds blank and without any video/audio ahead while clipping from source. Is there any solution to this ?

    &#xA;

    The code for the script is given below (was taken from here https://github.com/occivink/mpv-scripts) :

    &#xA;

    local utils = require "mp.utils"&#xA;local msg = require "mp.msg"&#xA;local options = require "mp.options"&#xA;&#xA;local ON_WINDOWS = (package.config:sub(1,1) ~= "/")&#xA;&#xA;local start_timestamp = nil&#xA;local profile_start = ""&#xA;&#xA;-- implementation detail of the osd message&#xA;local timer = nil&#xA;local timer_duration = 2&#xA;&#xA;-- folder creation if it doesnt exist&#xA;function exists(file)&#xA;   local ok, err, code = os.rename(file, file)&#xA;   if not ok then&#xA;      if code == 13 then&#xA;         return true&#xA;      end&#xA;   end&#xA;   return ok, err&#xA;end&#xA;&#xA;--- Check if a directory exists in this path&#xA;function create_dir(path)&#xA;    local dir = "\"" .. path .. "\""&#xA;    if not exists(path .."/") then&#xA;        os.execute("mkdir " .. dir)&#xA;    end&#xA;end&#xA;&#xA;function append_table(lhs, rhs)&#xA;    for i = 1,#rhs do&#xA;        lhs[#lhs&#x2B;1] = rhs[i]&#xA;    end&#xA;    return lhs&#xA;end&#xA;&#xA;function file_exists(name)&#xA;    local f = io.open(name, "r")&#xA;    if f ~= nil then&#xA;        io.close(f)&#xA;        return true&#xA;    else&#xA;        return false&#xA;    end&#xA;end&#xA;&#xA;function get_extension(path)&#xA;    local candidate = string.match(path, "%.([^.]&#x2B;)$")&#xA;    if candidate then&#xA;        for _, ext in ipairs({ "mkv", "webm", "mp4", "avi" }) do&#xA;            if candidate == ext then&#xA;                return candidate&#xA;            end&#xA;        end&#xA;    end&#xA;    return "mkv"&#xA;end&#xA;&#xA;function get_output_string(dir, format, input, extension, title, from, to, profile)&#xA;    local res = utils.readdir(dir)&#xA;    if not res then&#xA;        return nil&#xA;    end&#xA;    local files = {}&#xA;    for _, f in ipairs(res) do&#xA;        files[f] = true&#xA;    end&#xA;    local output = format&#xA;    output = string.gsub(output, "$f", function() return input end)&#xA;    output = string.gsub(output, "$t", function() return title end)&#xA;    output = string.gsub(output, "$s", function() return seconds_to_time_string(from, true) end)&#xA;    output = string.gsub(output, "$e", function() return seconds_to_time_string(to, true) end)&#xA;    output = string.gsub(output, "$d", function() return seconds_to_time_string(to-from, true) end)&#xA;    output = string.gsub(output, "$x", function() return extension end)&#xA;    output = string.gsub(output, "$p", function() return profile end)&#xA;    if ON_WINDOWS then&#xA;        output = string.gsub(output, "[/\\|&lt;>?:\"*]", "_")&#xA;    end&#xA;    if not string.find(output, "$n") then&#xA;        return files[output] and nil or output&#xA;    end&#xA;    local i = 1&#xA;    while true do&#xA;        local potential_name = string.gsub(output, "$n", tostring(i))&#xA;        if not files[potential_name] then&#xA;            return potential_name&#xA;        end&#xA;        i = i &#x2B; 1&#xA;    end&#xA;end&#xA;&#xA;function get_video_filters()&#xA;    local filters = {}&#xA;    for _, vf in ipairs(mp.get_property_native("vf")) do&#xA;        local name = vf["name"]&#xA;        name = string.gsub(name, &#x27;^lavfi%-&#x27;, &#x27;&#x27;)&#xA;        local filter&#xA;        if name == "crop" then&#xA;            local p = vf["params"]&#xA;            filter = string.format("crop=%d:%d:%d:%d", p.w, p.h, p.x, p.y)&#xA;        elseif name == "mirror" then&#xA;            filter = "hflip"&#xA;        elseif name == "flip" then&#xA;            filter = "vflip"&#xA;        elseif name == "rotate" then&#xA;            local rotation = vf["params"]["angle"]&#xA;            -- rotate is NOT the filter we want here&#xA;            if rotation == "90" then&#xA;                filter = "transpose=clock"&#xA;            elseif rotation == "180" then&#xA;                filter = "transpose=clock,transpose=clock"&#xA;            elseif rotation == "270" then&#xA;                filter = "transpose=cclock"&#xA;            end&#xA;        end&#xA;        filters[#filters &#x2B; 1] = filter&#xA;    end&#xA;    return filters&#xA;end&#xA;&#xA;function get_input_info(default_path, only_active)&#xA;    local accepted = {&#xA;        video = true,&#xA;        audio = not mp.get_property_bool("mute"),&#xA;        sub = mp.get_property_bool("sub-visibility")&#xA;    }&#xA;    local ret = {}&#xA;    for _, track in ipairs(mp.get_property_native("track-list")) do&#xA;        local track_path = track["external-filename"] or default_path&#xA;        if not only_active or (track["selected"] and accepted[track["type"]]) then&#xA;            local tracks = ret[track_path]&#xA;            if not tracks then&#xA;                ret[track_path] = { track["ff-index"] }&#xA;            else&#xA;                tracks[#tracks &#x2B; 1] = track["ff-index"]&#xA;            end&#xA;        end&#xA;    end&#xA;    return ret&#xA;end&#xA;&#xA;function seconds_to_time_string(seconds, full)&#xA;    local ret = string.format("%02d:%02d.%03d"&#xA;        , math.floor(seconds / 60) % 60&#xA;        , math.floor(seconds) % 60&#xA;        , seconds * 1000 % 1000&#xA;    )&#xA;    if full or seconds > 3600 then&#xA;        ret = string.format("%d:%s", math.floor(seconds / 3600), ret)&#xA;    end&#xA;    return ret&#xA;end&#xA;&#xA;function start_encoding(from, to, settings)&#xA;    local args = {&#xA;        settings.ffmpeg_command,&#xA;        "-loglevel", "panic", "-hide_banner",&#xA;    }&#xA;    local append_args = function(table) args = append_table(args, table) end&#xA;&#xA;    local path = mp.get_property("path")&#xA;    local is_stream = not file_exists(path)&#xA;    if is_stream then&#xA;        path = mp.get_property("stream-path")&#xA;    end&#xA;&#xA;    local track_args = {}&#xA;    local start = seconds_to_time_string(from, false)&#xA;    local input_index = 0&#xA;    for input_path, tracks in pairs(get_input_info(path, settings.only_active_tracks)) do&#xA;       append_args({&#xA;            "-ss", start,&#xA;            "-i", input_path,&#xA;        })&#xA;        if settings.only_active_tracks then&#xA;            for _, track_index in ipairs(tracks) do&#xA;                track_args = append_table(track_args, { "-map", string.format("%d:%d", input_index, track_index)})&#xA;            end&#xA;        else&#xA;            track_args = append_table(track_args, { "-map", tostring(input_index)})&#xA;        end&#xA;        input_index = input_index &#x2B; 1&#xA;    end&#xA;&#xA;    append_args({"-to", tostring(to-from)})&#xA;    append_args(track_args)&#xA;&#xA;    -- apply some of the video filters currently in the chain&#xA;    local filters = {}&#xA;    if settings.preserve_filters then&#xA;        filters = get_video_filters()&#xA;    end&#xA;    if settings.append_filter ~= "" then&#xA;        filters[#filters &#x2B; 1] = settings.append_filter&#xA;    end&#xA;    if #filters > 0 then&#xA;        append_args({ "-filter:v", table.concat(filters, ",") })&#xA;    end&#xA;&#xA;    -- split the user-passed settings on whitespace&#xA;    for token in string.gmatch(settings.codec, "[^%s]&#x2B;") do&#xA;        args[#args &#x2B; 1] = token&#xA;    end&#xA;&#xA;    -- path of the output&#xA;    local output_directory = mp.get_property("options/screenshot-directory")&#xA;    -- local checkbool = exists(output_directory.."/")&#xA;    -- mp.osd_message("" .. type(checkbool), timer_duration)&#xA;    -- if not checkbool then    &#xA;    --     os.execute("mkdir" .. output_directory)&#xA;    -- end&#xA;    if output_directory == "" then&#xA;        if is_stream then&#xA;            output_directory = "."&#xA;        else&#xA;            output_directory, _ = utils.split_path(path)&#xA;        end&#xA;    else&#xA;        output_directory = string.gsub(output_directory, "^~", os.getenv("HOME") or "~")&#xA;    end&#xA;    local input_name = mp.get_property("filename/no-ext") or "encode"&#xA;    local title = mp.get_property("media-title")&#xA;    local extension = get_extension(path)&#xA;    local output_name = get_output_string(output_directory, settings.output_format, input_name, extension, title, from, to, settings.profile)&#xA;    if not output_name then&#xA;        mp.osd_message("Invalid path " .. output_directory)&#xA;        return&#xA;    end&#xA;    args[#args &#x2B; 1] = utils.join_path(output_directory, output_name)&#xA;&#xA;    if settings.print then&#xA;        local o = ""&#xA;        -- fuck this is ugly&#xA;        for i = 1, #args do&#xA;            local fmt = ""&#xA;            if i == 1 then&#xA;                fmt = "%s%s"&#xA;            elseif i >= 2 and i &lt;= 4 then&#xA;                fmt = "%s"&#xA;            elseif args[i-1] == "-i" or i == #args or args[i-1] == "-filter:v" then&#xA;                fmt = "%s &#x27;%s&#x27;"&#xA;            else&#xA;                fmt = "%s %s"&#xA;            end&#xA;            o = string.format(fmt, o, args[i])&#xA;        end&#xA;        print(o)&#xA;    end&#xA;    if settings.detached then&#xA;        utils.subprocess_detached({ args = args })&#xA;    else&#xA;        local res = utils.subprocess({ args = args, max_size = 0, cancellable = false })&#xA;        if res.status == 0 then&#xA;            mp.osd_message("Finished encoding succesfully")&#xA;        else&#xA;            mp.osd_message("Failed to encode, check the log")&#xA;        end&#xA;    end&#xA;end&#xA;&#xA;function clear_timestamp()&#xA;    timer:kill()&#xA;    start_timestamp = nil&#xA;    profile_start = ""&#xA;    mp.remove_key_binding("encode-ESC")&#xA;    mp.remove_key_binding("encode-ENTER")&#xA;    mp.osd_message("", 0)&#xA;end&#xA;&#xA;function set_timestamp(profile)&#xA;    if not mp.get_property("path") then&#xA;        mp.osd_message("No file currently playing")&#xA;        return&#xA;    end&#xA;    if not mp.get_property_bool("seekable") then&#xA;        mp.osd_message("Cannot encode non-seekable media")&#xA;        return&#xA;    end&#xA;    create_dir(mp.get_property("options/screenshot-directory"))&#xA;    if not start_timestamp or profile ~= profile_start then&#xA;        profile_start = profile&#xA;        start_timestamp = mp.get_property_number("time-pos")&#xA;        local msg = function()&#xA;            mp.osd_message(&#xA;                string.format("encode [%s]: waiting for end timestamp", profile or "default"),&#xA;                timer_duration&#xA;            )&#xA;        end&#xA;        msg()&#xA;        timer = mp.add_periodic_timer(timer_duration, msg)&#xA;        mp.add_forced_key_binding("ESC", "encode-ESC", clear_timestamp)&#xA;        mp.add_forced_key_binding("ENTER", "encode-ENTER", function() set_timestamp(profile) end)&#xA;    else&#xA;        local from = start_timestamp&#xA;        local to = mp.get_property_number("time-pos")&#xA;        if to &lt;= from then&#xA;            mp.osd_message("Second timestamp cannot be before the first", timer_duration)&#xA;            timer:kill()&#xA;            timer:resume()&#xA;            return&#xA;        end&#xA;        clear_timestamp()&#xA;        mp.osd_message(string.format("Encoding from %s to %s"&#xA;            , seconds_to_time_string(from, false)&#xA;            , seconds_to_time_string(to, false)&#xA;        ), timer_duration)&#xA;        -- include the current frame into the extract&#xA;        local fps = mp.get_property_number("container-fps") or 30&#xA;        to = to &#x2B; 1 / fps / 2&#xA;        local settings = {&#xA;            detached = false,&#xA;            container = "",&#xA;            only_active_tracks = false,&#xA;            preserve_filters = true,&#xA;            append_filter = "",&#xA;            codec = "-c:v libvpx-vp9 -lossless 1 -b:v 1000k -deadline good",&#xA;            output_format = "$f_$n.webm",&#xA;            output_directory = "",&#xA;            ffmpeg_command = "ffmpeg",&#xA;            print = true,&#xA;        }&#xA;        if profile then&#xA;            options.read_options(settings, profile)&#xA;            if settings.container ~= "" then&#xA;                msg.warn("The &#x27;container&#x27; setting is deprecated, use &#x27;output_format&#x27; now")&#xA;                settings.output_format = settings.output_format .. "." .. settings.container&#xA;            end&#xA;            settings.profile = profile&#xA;        else&#xA;            settings.profile = "default"&#xA;        end        &#xA;        start_encoding(from, to, settings)&#xA;    end&#xA;end&#xA;&#xA;mp.add_key_binding(nil, "set-timestamp", set_timestamp)&#xA;

    &#xA;

  • match an image to a specific frame within a video with ffmpeg

    2 juin 2021, par az0

    I have some images that were taken from a video via screen capture. I would like to know when in the video these images appear (timestamps). Is there a way to programmatically match an image with a specific frame in a video using ffmpeg or some other tool ?

    &#xA;&#xA;

    I am very open to different technologies as I'm eager to automate this. It would be extremely time consuming to do this manually.

    &#xA;