如何使用 Processing 创建半透明的音频反应叠加层?
How to create a translucent audio-reactive overlay with Processing?
我对这个问题进行了广泛的研究,但找不到任何有用的答案。基本上,我想创建一个半透明(或半透明)的音频反应叠加层,可以将其转置到通用视频文件上。这个想法是让视频看起来与音轨一起跳动。
我想我可以用Processing和minim库来实现这个效果,但我不知道如何制定草图。输出应为 1920x1080,脉动叠加层应产生充满活力的光度感(例如,亮度为 30-50%,不透明度可能为 25-50% 的浅色)。
我正在使用@george-profenza 提供的草图更新这个挑战(修改为使用视频而不是摄像头输入):
import processing.video.*;
Movie movie;
PGraphics overlay;
import ddf.minim.*;
Minim minim;
AudioInput in;
void setup(){
size(320,240);
movie = new Movie(this, "input.mp4");
movie.play();
// setup sound
minim = new Minim(this);
in = minim.getLineIn();
// setup overlay
overlay = createGraphics(width,height);
// initial draw attributes
overlay.beginDraw();
overlay.strokeWeight(3);
overlay.rectMode(CENTER);
overlay.noFill();
overlay.stroke(255,255,255,32);
overlay.endDraw();
}
void draw(){
//update overlay based on audio data
overlay.beginDraw();
overlay.background(0,0);
for(int i = 0; i < in.bufferSize() - 1; i++)
{
overlay.line( i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50 );
overlay.line( i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50 );
}
overlay.endDraw();
//render video then overlay composite
image(movie,0,0);
image(overlay,0,0);
}
// update movie
void movieEvent(Movie m){
m.read();
}
大概这个草图有效,但不幸的是,底层 processing.video
(GStreamer 1+) 库似乎在 Ubuntu 上出现故障(并且似乎没有办法更新根据 GitHub.
上的 issue #90,带有社区提供的叉子之一的图书馆
如果有人可以提出解决此问题的方法或有其他解决方案,我将不胜感激。
首先要熟悉编写视频文件,您需要以某种方式保存输出。然后确保您可以正确读取文件。除非您想使用来自麦克风的音频,否则您需要访问视频文件的音频(?)。
透明覆盖很容易,只需使用较少的 alpha
进行绘制
这是一个广泛的问题。我将介绍几个方面:
- 半透明(音频反应)叠加层: 查看 PGraphics。这就像 Processing 中的图层。您可以在 PGraphics 中绘制(具有半透明性等),然后按您想要的顺序进行渲染。请参阅下面的注释示例
- audio-reactive: 你可以使用 minim 是使用响度、FFT 数据或其他一些可以进行更高级音频分析的软件,你可以从中导出数据进行处理以读取.
- 1920x1080 输出:根据我的个人经验,在撰写本文时,我惊讶地看到在 Processing 中播放 1080p 视频还可以,但不是非常清晰(我会体验到每隔一段时间就会错开,在具有 16GB RAM 的 macbook 和同样具有 16GB RAM 的 PC 上进行测试)。在顶部进行声音分析和叠加图形可能会进一步降低性能,主要问题是音频和合成图形之间的同步,即您想实时进行此操作。
如果您只是想输出具有漂亮的音频响应图形的视频,但不需要实时,我建议您采用更 "offline" 的方法:
- 预分析音频数据,因此只有您需要驱动视觉效果的数据才存在(可以像响度一样简单)
- 使用实时音频和无视频制作低分辨率视觉效果原型,以查看 looks/feels 是否正常
- 以 1080p 逐帧渲染视频 + 视觉效果(具有声音映射属性),然后渲染同步音频(可以使用 After Effects、
ffmpeg
等)
这里有一个非常基本的概念证明草图供参考,它演示了:
- 使用叠加图形
- 将覆盖图形更新为音频反应(Minim MonitorInput 示例)
- 合成视频 + 叠加层
注意低分辨率视频的大小。
import processing.video.*;
Capture cam;
PGraphics overlay;
import ddf.minim.*;
Minim minim;
AudioInput in;
void setup(){
size(320,240);
// setup video (may be video instead of webcam in your case)
cam = new Capture(this,width,height);
cam.start();
// setup sound
minim = new Minim(this);
in = minim.getLineIn();
// setup overlay
overlay = createGraphics(width,height);
// initial draw attributes
overlay.beginDraw();
overlay.strokeWeight(3);
overlay.rectMode(CENTER);
overlay.noFill();
overlay.stroke(255,255,255,32);
overlay.endDraw();
}
void draw(){
//update overlay based on audio data
overlay.beginDraw();
overlay.background(0,0);
for(int i = 0; i < in.bufferSize() - 1; i++)
{
overlay.line( i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50 );
overlay.line( i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50 );
}
overlay.endDraw();
//render video then overlay composite
image(cam,0,0);
image(overlay,0,0);
}
// update video (may be movieEvent(Movie m) for you
void captureEvent(Capture c){
c.read();
}
我对这个问题进行了广泛的研究,但找不到任何有用的答案。基本上,我想创建一个半透明(或半透明)的音频反应叠加层,可以将其转置到通用视频文件上。这个想法是让视频看起来与音轨一起跳动。
我想我可以用Processing和minim库来实现这个效果,但我不知道如何制定草图。输出应为 1920x1080,脉动叠加层应产生充满活力的光度感(例如,亮度为 30-50%,不透明度可能为 25-50% 的浅色)。
我正在使用@george-profenza 提供的草图更新这个挑战(修改为使用视频而不是摄像头输入):
import processing.video.*;
Movie movie;
PGraphics overlay;
import ddf.minim.*;
Minim minim;
AudioInput in;
void setup(){
size(320,240);
movie = new Movie(this, "input.mp4");
movie.play();
// setup sound
minim = new Minim(this);
in = minim.getLineIn();
// setup overlay
overlay = createGraphics(width,height);
// initial draw attributes
overlay.beginDraw();
overlay.strokeWeight(3);
overlay.rectMode(CENTER);
overlay.noFill();
overlay.stroke(255,255,255,32);
overlay.endDraw();
}
void draw(){
//update overlay based on audio data
overlay.beginDraw();
overlay.background(0,0);
for(int i = 0; i < in.bufferSize() - 1; i++)
{
overlay.line( i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50 );
overlay.line( i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50 );
}
overlay.endDraw();
//render video then overlay composite
image(movie,0,0);
image(overlay,0,0);
}
// update movie
void movieEvent(Movie m){
m.read();
}
大概这个草图有效,但不幸的是,底层 processing.video
(GStreamer 1+) 库似乎在 Ubuntu 上出现故障(并且似乎没有办法更新根据 GitHub.
如果有人可以提出解决此问题的方法或有其他解决方案,我将不胜感激。
首先要熟悉编写视频文件,您需要以某种方式保存输出。然后确保您可以正确读取文件。除非您想使用来自麦克风的音频,否则您需要访问视频文件的音频(?)。 透明覆盖很容易,只需使用较少的 alpha
进行绘制这是一个广泛的问题。我将介绍几个方面:
- 半透明(音频反应)叠加层: 查看 PGraphics。这就像 Processing 中的图层。您可以在 PGraphics 中绘制(具有半透明性等),然后按您想要的顺序进行渲染。请参阅下面的注释示例
- audio-reactive: 你可以使用 minim 是使用响度、FFT 数据或其他一些可以进行更高级音频分析的软件,你可以从中导出数据进行处理以读取.
- 1920x1080 输出:根据我的个人经验,在撰写本文时,我惊讶地看到在 Processing 中播放 1080p 视频还可以,但不是非常清晰(我会体验到每隔一段时间就会错开,在具有 16GB RAM 的 macbook 和同样具有 16GB RAM 的 PC 上进行测试)。在顶部进行声音分析和叠加图形可能会进一步降低性能,主要问题是音频和合成图形之间的同步,即您想实时进行此操作。
如果您只是想输出具有漂亮的音频响应图形的视频,但不需要实时,我建议您采用更 "offline" 的方法:
- 预分析音频数据,因此只有您需要驱动视觉效果的数据才存在(可以像响度一样简单)
- 使用实时音频和无视频制作低分辨率视觉效果原型,以查看 looks/feels 是否正常
- 以 1080p 逐帧渲染视频 + 视觉效果(具有声音映射属性),然后渲染同步音频(可以使用 After Effects、
ffmpeg
等)
这里有一个非常基本的概念证明草图供参考,它演示了:
- 使用叠加图形
- 将覆盖图形更新为音频反应(Minim MonitorInput 示例)
- 合成视频 + 叠加层
注意低分辨率视频的大小。
import processing.video.*;
Capture cam;
PGraphics overlay;
import ddf.minim.*;
Minim minim;
AudioInput in;
void setup(){
size(320,240);
// setup video (may be video instead of webcam in your case)
cam = new Capture(this,width,height);
cam.start();
// setup sound
minim = new Minim(this);
in = minim.getLineIn();
// setup overlay
overlay = createGraphics(width,height);
// initial draw attributes
overlay.beginDraw();
overlay.strokeWeight(3);
overlay.rectMode(CENTER);
overlay.noFill();
overlay.stroke(255,255,255,32);
overlay.endDraw();
}
void draw(){
//update overlay based on audio data
overlay.beginDraw();
overlay.background(0,0);
for(int i = 0; i < in.bufferSize() - 1; i++)
{
overlay.line( i, 50 + in.left.get(i)*50, i+1, 50 + in.left.get(i+1)*50 );
overlay.line( i, 150 + in.right.get(i)*50, i+1, 150 + in.right.get(i+1)*50 );
}
overlay.endDraw();
//render video then overlay composite
image(cam,0,0);
image(overlay,0,0);
}
// update video (may be movieEvent(Movie m) for you
void captureEvent(Capture c){
c.read();
}