mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
28.4k stars 2.91k forks source link

Dummy video/audio tracks for generative filters and encoding mode #8565

Open twilson90 opened 3 years ago

twilson90 commented 3 years ago

I'm trying to implement a basic audio visualizer for mpv using an ffmpeg filter: [a]showwaves=mode=line:s=hd480:colors=White[v] The only problem is, when mpv opens an audio file it doesn't initialize a video track so my video filter has nothing to output to.

It is possible to render a 'dummy' video track using "video-add" (currently broken but working in older builds) in a lua script. Something like: video-add av://lavfi:color=c=black:s=1920x1080:r=30

However this is not ideal for seeking as the dummy track has to render linearly, so with an hour-long piece of audio seeking towards the end will result in the player stalling for ages as it renders 60 minutes of black.

Having proper dummy audio/video tracks would also be very helpful for encoding mode, where a playlist may include files with video and/or audio. Initializing an audio file after a video file in a playlist produces a broken media stream. I currently get around it by adding my ghetto av:// tracks in lua but again it's really impractical for seeking large media files.

richardpl commented 3 years ago

You are a bit confused, A->V is complex filtering and need -lavfi-complex

twilson90 commented 3 years ago

lavfi-complex is exactly what I was looking for :) Just tried this and it does exactly what I want: mpv "audio.mp3" --lavfi-complex=[aid1]asplit[a1][ao];[a1]showwaves=mode=line:s=hd480:colors=White[vo] Thanks.

twilson90 commented 3 years ago

I spoke too soon. There is still an issue unfortunately with encoding mode (as usual).

If I play an audio file with lavfi-complex generated video, followed by a normal video in a playlist, it works.

If I play a normal video and then the audio file with lavfi-complex generated video, I get 'Failed to initialize audio driver 'lavc' when it tries to play the next track. Every time. I've made sure to set the pixel format to the same, the same video dimensions. No matter what it just fails.

Here's my command:

mpv --o=out.mkv --of=matroska --ovc=libx264 --oac=aac --log-file=log.txt --script=test.lua 3.mkv 1.mka --vf=format=yuv420p

test.lua:

local msg = require("mp.msg")
local utils = require("mp.utils")

mp.add_hook("on_preloaded", 10, function ()
    local lavfi_complex = ""
    local has_video = false
    local has_audio = false
    local track_list = mp.get_property_native("track-list")
    for _,t in pairs(track_list) do
        if t.type == "video" and not t.albumart then has_video = true end
        if t.type == "audio" then has_audio = true end
    end
    if not has_video then
        local scale = "1280x720"
        lavfi_complex = "[aid1]asplit[a1][ao];[a1]showwaves=mode=line:s="..scale..":colors=White:r=30[wf];color=c=black:s="..scale.."[co];[co][wf]overlay=shortest=1,format=yuv420p[vo]"
    elseif not has_audio then
        lavfi_complex = "anullsrc,aformat=sample_fmts=s16:sample_rates=48000:channel_layouts=stereo[ao]"
    end
    mp.set_property_native("lavfi-complex", lavfi_complex)
    msg.info(lavfi_complex)
end)

log: log.txt