Skip to content

Latest commit

 

History

History
86 lines (73 loc) · 3.18 KB

File metadata and controls

86 lines (73 loc) · 3.18 KB
Error in user YAML: (<unknown>): found a tab character that violate indentation while scanning a plain scalar at line 3 column 3
---
- oeasy Python 0741
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
- 本教程同步发布在: 
	- 个人网站: `https://oeasy.org` 
	- 蓝桥云课: `https://www.lanqiao.cn/courses/3584` 
	- GitHub: `https://github.com/overmind1980/oeasy-python-tutorial` 
	- Gitee: `https://gitee.com/overmind1980/oeasypython` 
---
import bpy
import wave
import numpy as np

def get_grease_pencil(gpencil_obj_name='GPencil') -> bpy.types.GreasePencil:
    if gpencil_obj_name not in bpy.context.scene.objects:
        bpy.ops.object.gpencil_add(location=(0, 0, 0), type='EMPTY')
        bpy.context.scene.objects[-1].name = gpencil_obj_name
    gpencil = bpy.context.scene.objects[gpencil_obj_name]
    return gpencil

def get_grease_pencil_layer(gpencil: bpy.types.GreasePencil, gpencil_layer_name='GP_Layer', clear_layer=False) -> bpy.types.GPencilLayer:
    if gpencil.data.layers and gpencil_layer_name in gpencil.data.layers:
        gpencil_layer = gpencil.data.layers[gpencil_layer_name]
    else:
        gpencil_layer = gpencil.data.layers.new(gpencil_layer_name, set_active=True)
    if clear_layer:
        gpencil_layer.clear()
    return gpencil_layer

def init_grease_pencil(gpencil_obj_name='GPencil', gpencil_layer_name='GP_Layer', clear_layer=True) -> bpy.types.GPencilLayer:
    gpencil = get_grease_pencil(gpencil_obj_name)
    gpencil_layer = get_grease_pencil_layer(gpencil, gpencil_layer_name, clear_layer=clear_layer)
    return gpencil_layer

def draw_waveform(gp_frame, samples, width, height):
    gp_stroke = gp_frame.strokes.new()
    gp_stroke.display_mode = '3DSPACE'
    gp_stroke.line_width = 50
    gp_stroke.material_index = 0
    gp_stroke.points.add(count=len(samples))
    
    max_amplitude = max(abs(samples))
    for i, sample in enumerate(samples):
        x = -10 + (i / len(samples)) * (width + 20)  # 从x=-10到x=10
        y = (sample / max_amplitude) * height / 2
        gp_stroke.points[i].co = (x, y, 0)
    return gp_stroke

def read_wave_file(file_path, downsample_factor=10):
    with wave.open(file_path, 'rb') as wf:
        sample_rate = wf.getframerate()
        n_frames = wf.getnframes()
        samples = np.frombuffer(wf.readframes(n_frames), dtype=np.int16)
    # Downsample the audio to reduce the number of points
    samples = samples[::downsample_factor]
    return samples, sample_rate // downsample_factor

# 音频文件路径
file_path = "/Users/easyo/Downloads/77777.WAV"

# 读取音频文件
samples, sample_rate = read_wave_file(file_path)

# 初始化 Grease Pencil
gp_layer = init_grease_pencil()

# 绘制音频波形
NUM_FRAMES = 300  # 增加帧数以延长动画
WIDTH = 20  # 调整宽度以适应新的x范围
HEIGHT = 5

bpy.context.scene.frame_start = 0
bpy.context.scene.frame_end = NUM_FRAMES

for frame_index in range(NUM_FRAMES):
    gp_frame = gp_layer.frames.new(frame_index)
    start = int((frame_index / NUM_FRAMES) * len(samples))
    end = int(((frame_index + 1) / NUM_FRAMES) * len(samples))
    draw_waveform(gp_frame, samples[start:end], WIDTH, HEIGHT)


  • 本文来自 oeasy Python 系统教程。
  • 想完整、扎实学 Python,
  • 搜索 oeasy 即可。