Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 21st March 2021, 14:45   #121  |  Link
forgetfool
Registered User
 
Join Date: Aug 2020
Posts: 33
Linux solution

As far as I understand, BAS is Windows only solution, right?

Is there a Linux audio plugin for VapourSynth? "vs.core.damb.Read()" seems to have no effect, i.e. at does not attach sound to video.
forgetfool is offline   Reply With Quote
Old 21st March 2021, 15:48   #122  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
Video and audio are separate entities in vaporsynth. You may define an av container that associates an audio node with a video node, but you cannot attach an audio node to a video node.

Last edited by feisty2; 21st March 2021 at 15:51.
feisty2 is offline   Reply With Quote
Old 23rd March 2021, 07:51   #123  |  Link
forgetfool
Registered User
 
Join Date: Aug 2020
Posts: 33
As for the first part of the question, someone mentioned that I need to manually compile BAS (that it works for them on Ubuntu).

As for the second part, about DAMB, ok, I understand the point, but how would you actually produce a video with a sound? What is wrong with the code below? I feel I am still missing some basic understanding.

import vapoursynth as vs
src = vs.core.ffms2.Source(video.avi')
src = vs.core.damb.Read(src, "audio.wav")
src.set_output()

I am reading the documentation nere: https://github.com/dubhater/vapoursynth-damb
forgetfool is offline   Reply With Quote
Old 23rd March 2021, 10:05   #124  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
Code:
class Muxer:
    def Render(self):
        self.VideoStream.set_output(0)
        self.AudioStream.set_output(1)

av = Muxer()
av.VideoStream = core.ffms2.Source('video.mov')
av.AudioStream = core.bas.Source('audio.wav')

av.Render()
edit:
and damb is obsolete (it is based on API v3 which has no native support for audio), don't use it.

Last edited by feisty2; 23rd March 2021 at 10:15.
feisty2 is offline   Reply With Quote
Old 24th March 2021, 14:36   #125  |  Link
jackoneill
unsigned int
 
jackoneill's Avatar
 
Join Date: Oct 2012
Location: 🇪🇺
Posts: 760
Quote:
Originally Posted by forgetfool View Post
As for the second part, about DAMB, ok, I understand the point, but how would you actually produce a video with a sound? What is wrong with the code below? I feel I am still missing some basic understanding.

import vapoursynth as vs
src = vs.core.ffms2.Source(video.avi')
src = vs.core.damb.Read(src, "audio.wav")
src.set_output()

I am reading the documentation nere: https://github.com/dubhater/vapoursynth-damb
It's useful if you want to trim/splice the audio at the same time as the video. You use Read right after your video source filter, trim and splice the video as needed, then at the end of the script you use Write to export the audio to a file. vspipe will still output just the video. If you use only Read then the audio will be read from the file and nothing else happens.
__________________
Buy me a "coffee" and/or hire me to write code!
jackoneill is offline   Reply With Quote
Old 26th March 2021, 04:04   #126  |  Link
forgetfool
Registered User
 
Join Date: Aug 2020
Posts: 33
Ok, so you are saying vspipe will never produce audio with video together, right?

I am now trying to use BestAudioSource plugin instad of DAMB (without much success either) -- see this thread: https://forum.doom9.org/showthread.p...=1#post1939019
forgetfool is offline   Reply With Quote
Old 26th March 2021, 12:06   #127  |  Link
jackoneill
unsigned int
 
jackoneill's Avatar
 
Join Date: Oct 2012
Location: 🇪🇺
Posts: 760
Quote:
Originally Posted by forgetfool View Post
Ok, so you are saying vspipe will never produce audio with video together, right?

I am now trying to use BestAudioSource plugin instad of DAMB (without much success either) -- see this thread: https://forum.doom9.org/showthread.p...=1#post1939019
Maybe with BestAudioSource it will. I'm not sure how it's supposed to work.
__________________
Buy me a "coffee" and/or hire me to write code!
jackoneill is offline   Reply With Quote
Old 26th March 2021, 12:28   #128  |  Link
DJATOM
Registered User
 
DJATOM's Avatar
 
Join Date: Sep 2010
Location: Ukraine, Bohuslav
Posts: 377
BAS uses AudioNode entity to represent audio data. Literally it's the same as VideoNode, but for audio clips. To draw data from it, user has to assign node to certain output, for example, audio.set_output(1) - assuming that your audio clip named audio.
__________________
Me on GitHub
PC Specs: Ryzen 5950X, 64 GB RAM, RTX 2070
DJATOM is offline   Reply With Quote
Old 23rd July 2021, 06:02   #129  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,377
Can you release an updated audio build when you get the chance ?

Thanks
poisondeathray is offline   Reply With Quote
Old 20th May 2022, 21:25   #130  |  Link
xekon
Registered User
 
Join Date: Jul 2011
Posts: 224
Quote:
Originally Posted by DJATOM View Post
I've done some modifications to make possible to add few Trim instances with each other. The code is now looks like that
Code:
from vapoursynth import core, VideoNode, AudioNode
from typing import Sequence, Union


class Trim:
    def __init__(self, clip: Union[AudioNode, Sequence], start: int = None, end: int = None, fps: Sequence = None) -> Union[AudioNode, tuple]:
        """ Convenient wrapper for trimming audio samples by frame numbers """
        if not start and not end:
            raise ValueError('Trim: missing "start" and/or "end" options.')

        self.vclip, self.aclip = None, None
        self.mode = 'audio'

        if isinstance(clip, Sequence) and len(clip) == 2:
            self.mode = 'video_audio'
            self.vclip, self.aclip = clip
            assert isinstance(
                self.vclip, VideoNode), 'Trim: first clip must be video.'
            assert isinstance(
                self.aclip, AudioNode), 'Trim: second clip must be audio.'
            self.vclip = core.std.Trim(self.vclip, start, end)

        elif isinstance(clip, AudioNode):
            self.aclip = clip
            if not fps:
                raise ValueError('Trim: missing "fps" option.')
        else:
            raise ValueError(
                'Trim: clip must be audio type or sequence with video and audio clips.')
        if isinstance(self.vclip, VideoNode) and not (self.vclip.fps.numerator == 0 and self.vclip.fps.denominator == 0) and fps is None:
            fps = (self.vclip.fps.numerator, self.vclip.fps.denominator)
        samples_per_video_frame = self.aclip.sample_rate / fps[0] * fps[1]
        audio_start, audio_end = start * \
            samples_per_video_frame, end * samples_per_video_frame
        self.aclip = core.std.AudioTrim(self.aclip, audio_start, audio_end)

    def __add__(self, other):
        if not isinstance(other, Trim):
            raise ValueError(f'Trim: impossible to operate on non-Trim inputs.')
        if self.mode == 'video_audio' and other.mode != 'video_audio':
            raise ValueError(
                'Trim: add failed. Probably you\'re mixing inconsistent instances (audio + video and audio or so).')
        if self.mode == 'video_audio':
            self.vclip += other.vclip
        self.aclip += other.aclip
        return self

    def data(self):
        if self.mode == 'video_audio':
            return self.vclip, self.aclip
        else:
            return self.aclip
But with class rewrite we need to call method data() to return clips
Code:
vclip, aclip = (Trim((vclip, aclip), 18544, 18582) + Trim((vclip, aclip), 18687, 18724) + Trim((vclip, aclip), 18792, 18861)).data()
I tried to find a way to implicitly return data on assignment, but it seems that's too tricky.
WORKS GREAT! I was ripping my hair out trying to figure out how to encode some video and audio using trim/audiotrim in vapoursynth, the ONLY example I could find for working with the audio in vapoursynth was on this page but it does not include how to trim in the example:

https://www.vapoursynth.com/2020/01/...-how-it-works/

This function is excellent and in my opinion needs more exposure, just try searching google for this:

Vapoursynth AudioTrim Example (spoiler you wont find this thread)

I ended up searching for

Vapoursynth "bas.Source"

Which still did not find this thread, but it did find this one https://forum.doom9.org/showthread.php?t=177337 in which somebody linked to this thread, so I finally found it.

What I think would be absolutely killer is if all the functions had a small minimal example script of how to use it, even better is if these examples were right on https://vsdb.top/ so when you search for a function there you can find a practical example of how to use it, this part of the site could also be community driven like a wiki...

Now that I have it working I am very very very pleased with this Audio support and the ability to do all of my processing with VapourSynth, its absolutely wonderful!
Attached Files
File Type: txt trim.vpy.txt (3.8 KB, 37 views)
xekon is offline   Reply With Quote
Old 20th May 2022, 21:30   #131  |  Link
xekon
Registered User
 
Join Date: Jul 2011
Posts: 224
trim.vpy:

Code:
import vapoursynth as vs
from typing import Sequence, Union
from vapoursynth import core, VideoNode, AudioNode

class Trim:
    def __init__(self, clip: Union[AudioNode, Sequence], start: int = None, end: int = None, fps: Sequence = None) -> Union[AudioNode, tuple]:
        """ Convenient wrapper for trimming audio samples by frame numbers """
        if not start and not end:
            raise ValueError('Trim: missing "start" and/or "end" options.')

        self.vclip, self.aclip = None, None
        self.mode = 'audio'

        if isinstance(clip, Sequence) and len(clip) == 2:
            self.mode = 'video_audio'
            self.vclip, self.aclip = clip
            assert isinstance(
                self.vclip, VideoNode), 'Trim: first clip must be video.'
            assert isinstance(
                self.aclip, AudioNode), 'Trim: second clip must be audio.'
            self.vclip = core.std.Trim(self.vclip, start, end)

        elif isinstance(clip, AudioNode):
            self.aclip = clip
            if not fps:
                raise ValueError('Trim: missing "fps" option.')
        else:
            raise ValueError(
                'Trim: clip must be audio type or sequence with video and audio clips.')
        if isinstance(self.vclip, VideoNode) and not (self.vclip.fps.numerator == 0 and self.vclip.fps.denominator == 0) and fps is None:
            fps = (self.vclip.fps.numerator, self.vclip.fps.denominator)
        samples_per_video_frame = self.aclip.sample_rate / fps[0] * fps[1]
        audio_start, audio_end = start * \
            samples_per_video_frame, end * samples_per_video_frame
        self.aclip = core.std.AudioTrim(self.aclip, audio_start, audio_end)

    def __add__(self, other):
        if not isinstance(other, Trim):
            raise ValueError(f'Trim: impossible to operate on non-Trim inputs.')
        if self.mode == 'video_audio' and other.mode != 'video_audio':
            raise ValueError(
                'Trim: add failed. Probably you\'re mixing inconsistent instances (audio + video and audio or so).')
        if self.mode == 'video_audio':
            self.vclip += other.vclip
        self.aclip += other.aclip
        return self

    def data(self):
        if self.mode == 'video_audio':
            return self.vclip, self.aclip
        else:
            return self.aclip

core = vs.core
video = core.ffms2.Source(source='/media/storage/vpy/over9000.mkv')
audio = core.bas.Source(source='/media/storage/vpy/over9000.flac', track=-1)

video, audio = (Trim((video, audio), 28406, 28491)).data()
#video, audio = (Trim((video, audio), 18544, 18582) + Trim((video, audio), 18687, 18724) + Trim((video, audio), 18792, 18861)).data()

video.set_output(0)
audio.set_output(1)

encode audio:
Code:
vspipe -o 1 -c wav /media/storage/vpy/trim.vpy - | ffmpeg -i pipe: -c:a aac -b:a 128k -ac 1 /media/storage/vpy/audio.aac
vspipe -o 1 -c wav /media/storage/vpy/trim.vpy - | ffmpeg -i pipe: -c:a libopus -b:a 96k -ac 1 /media/storage/vpy/audio.opus
encode video with previously encoded audio:
Code:
vspipe -o 0 -c y4m /media/storage/vpy/trim.vpy - | ffmpeg -i pipe: -i /media/storage/vpy/audio.aac -c:v libx264 -threads 1 -profile:v High \
 -level 4.1 -preset veryslow -crf 18 -x264-params "ref=6:bframes=16:merange=32:fast-pskip=0" -c:a copy "/media/storage/vpy/trim-x264.mkv"
vspipe -o 0 -c y4m /media/storage/vpy/trim.vpy - | ffmpeg -i pipe: -i /media/storage/vpy/audio.aac -c:v librav1e -qp 50 -speed 2 \
 -tiles 1 -tile-columns 1 -tile-rows 1 -c:a copy "/media/storage/vpy/trim-av1.mkv"
remove temporary audio files:
Code:
rm -rf /media/storage/vpy/audio.aac /media/storage/vpy/audio.opus
vmaf check:
Code:
ffmpeg -i /media/storage/vpy/trim-x264.mkv -i /media/storage/vpy/trim-av1.mkv -lavfi libvmaf='feature=name=psnr|name=ciede' -f null -

Last edited by xekon; 20th May 2022 at 21:34.
xekon is offline   Reply With Quote
Old 20th May 2022, 21:53   #132  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,555
I guess some easy way to trim audio along with video would be useful. My proposal is this:
Extend Trim like this:
Code:
std.Trim(vnode clip[, int first=0, int last, int length, anode[] audio])
If audio clips are supplied then the output in python will be a dict
Code:
{clip: <video here>, audio: <array of trimmed audio clips>}
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 21st May 2022, 02:12   #133  |  Link
xekon
Registered User
 
Join Date: Jul 2011
Posts: 224
A built in and officially supported method of trimming both the audio and the video with one or more range of frames would be wonderful!

I am sure however you decide to do it will be Awesome!
xekon is offline   Reply With Quote
Old 23rd May 2022, 15:08   #134  |  Link
PatchWorKs
Registered User
 
PatchWorKs's Avatar
 
Join Date: Aug 2002
Location: Italy
Posts: 304
Very interesting.

Do you think some Python Audio Restoration Suite functions can be "ported" to VS ?

From thair git:
Quote:
A set of tools to restore audio quality from a variety of old analog sources, such as tape, cassettes, acetates and vinyl.

Features
  • Wow & Flutter Removal
  • Speed matching to hum frequency
  • EQ matching with differential EQ
  • Spectral Temporal Alignment
  • Automatic Dropout Restoration
  • Spectral Expander / Decompressor
Hope that inspires !
__________________
Hybrid Multimedia Production Suite will be a platform-indipendent open source suite for advanced audio/video contents production.

Official git: https://www.forart.it/HyMPS/
PatchWorKs is offline   Reply With Quote
Old 23rd May 2022, 20:48   #135  |  Link
unix
Registered User
 
Join Date: Aug 2015
Posts: 47
Quote:
Originally Posted by Myrsloik View Post
I guess some easy way to trim audio along with video would be useful. My proposal is this:
Extend Trim like this:
Code:
std.Trim(vnode clip[, int first=0, int last, int length, anode[] audio])
If audio clips are supplied then the output in python will be a dict
Code:
{clip: <video here>, audio: <array of trimmed audio clips>}
Can you elaborate and give us an example
unix is offline   Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 04:50.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.