代码运行后提示: [00:00<?, ?frame/s]c:\users\wth\.spyder-py3\音乐随机视频-18-0602.py:121: DeprecationWarning: Conversion of an array with ndim > 0 to a scalar is deprecated, and will error in future. Ensure you extract a single element from your array before performing this operation. (Deprecated NumPy 1.25.) n_particles = int(current_rms * tempo * 0.5) 根据提示修改代码,输出修改后能完成所有功能的全部代码。
时间: 2025-08-07 15:17:31 浏览: 19
<think>好的,我现在需要解决用户提供的代码中的一个DeprecationWarning问题。这个警告提示在将多维数组转换为标量时存在问题,特别是在计算n_particles =int(current_rms* tempo*0.5)这一行。用户希望我修改代码,消除这个警告,并确保所有功能正常运行。首先,我需要理解这个警告的原因。DeprecationWarning指出将ndim>0的数组转换为标量已被弃用,未来会报错。这意味着current_rms可能是一个数组而非单个值,导致在乘法时出现问题。current_rms是从librosa.feature.rms中获取的,而rms是一个一维数组,每个元素代表不同时间帧的均方根能量。用户的问题出现在current_rms= rms[frame_idx% len(rms)],这里frame_idx可能是一个整数,但rms是一个数组,所以current_rms实际上是一个标量值。然而,如果frame_idx的计算方式有误,或者rms的结构不同,可能导致current_rms仍然是一个数组。例如,如果rms是二维的,取出来的元素可能仍是一个数组,导致在乘法时出现数组与标量的操作,从而触发警告。接下来,我需要检查代码中涉及current_rms的部分。在原来的代码中,current_rms被用来计算n_particles,即粒子数量。如果current_rms是一个数组而不是标量,那么current_rms *tempo *0.5会得到一个数组,转换为整数时会引发问题。解决方法是将current_rms显式转换为标量。可以使用.item()方法从numpy数组中提取单个元素。例如,current_rms =rms[frame_idx %len(rms)].item()。这样可以确保current_rms是一个标量值,而不是一个数组,从而避免警告。
同时,需要检查其他类似的地方是否存在同样的问题,比如current_centroid的处理。spectral_centroid也是一个一维数组,同样需要使用.item()来提取标量值。
此外,还需验证修改后的代码是否会影响原有功能。例如,确保提取的current_rms和current_centroid是正确的数值,粒子生成的数量和颜色映射仍然符合预期。最后,测试修改后的代码,确保没有引入新的错误,并且DeprecationWarning已经消除。同时,保持所有功能如粒子生成、圆环更新、颜色混合等正常工作。</think>以下是修正numpy标量转换警告的完整代码:
```python
import librosa
import librosa.display
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FFMpegWriter
from matplotlib.collections import EllipseCollection
from matplotlib.patches import Arc
import colorsys
from tqdm import tqdm
import subprocess
import os
# 初始化参数
audio_path = "input.mp3"
output_path = "output.mp4"
FPS = 30
WIDTH, HEIGHT = 1920, 1080
DPI = 300
def load_audio(path):
y, sr = librosa.load(path, sr=None, mono=True)
duration = librosa.get_duration(y=y, sr=sr)
n_fft = 2048
hop_length = 512
S = np.abs(librosa.stft(y, n_fft=n_fft, hop_length=hop_length))
tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr, hop_length=hop_length)
beat_times = librosa.frames_to_time(beat_frames, sr=sr, hop_length=hop_length)
rms = librosa.feature.rms(y=y, frame_length=n_fft, hop_length=hop_length)[0]
spectral_centroid = librosa.feature.spectral_centroid(y=y, sr=sr, n_fft=n_fft, hop_length=hop_length)[0]
return y, sr, S, tempo, beat_times, rms, spectral_centroid, duration
y, sr, S, tempo, beat_times, rms, spectral_centroid, duration = load_audio(audio_path)
# 可视化参数
n_notes = 12
max_radius = 300
ring_width = 20
ring_gap = 10
canvas_width = WIDTH/DPI
canvas_height = HEIGHT/DPI
fig = plt.figure(figsize=(canvas_width, canvas_height), dpi=DPI, facecolor='black')
ax = fig.add_axes([0, 0, 1, 1], facecolor='black')
ax.set_aspect('equal')
ax.set_xlim(0, 1)
ax.set_ylim(0, 1)
ax.axis('off')
pixel_to_norm = 1 / (DPI * canvas_height)
arcs = []
for i in range(n_notes):
radius_pixels = max_radius - i*(ring_width + ring_gap)
radius_norm = radius_pixels * pixel_to_norm
arc = Arc(
(0.5, 0.33),
width=2*radius_norm,
height=2*radius_norm,
theta1=0,
theta2=0,
lw=ring_width * pixel_to_norm * DPI,
color=plt.cm.coolwarm(i/n_notes),
fill=False,
capstyle='round'
)
arcs.append(arc)
ax.add_patch(arc)
writer = FFMpegWriter(fps=FPS, metadata=dict(title='Audio Visualizer', artist='Python'))
def frame_generator():
total_frames = int(duration * FPS)
for frame in range(total_frames):
yield frame / FPS
def frequency_to_color(freq, positive=True):
min_freq = 400e12
max_freq = 790e12
freq = np.clip(freq, min_freq, max_freq)
hue = (freq - min_freq) / (max_freq - min_freq) if positive else 1 - (freq - min_freq)/(max_freq - min_freq)
hue = np.clip(hue, 0.0, 1.0)
return colorsys.hsv_to_rgb(hue, 1.0, 1.0)
with writer.saving(fig, "temp_video.mp4", dpi=DPI):
total_frames = int(duration * FPS)
particle_dtype = np.dtype([
('pos', 'f4', 2),
('color', 'f4', 4),
('size', 'f4'),
('alpha', 'f4')
])
particles = np.empty(0, dtype=particle_dtype)
with tqdm(total=total_frames, desc="生成视频帧", unit="frame") as pbar:
for t in frame_generator():
for coll in list(ax.collections):
coll.remove()
frame_idx = int(t * FPS)
# 使用.item()显式转换为标量
current_rms = rms[frame_idx % len(rms)].item() # 关键修改点
current_centroid = spectral_centroid[frame_idx % len(spectral_centroid)].item()
is_beat = np.any(np.abs(beat_times - t) < 0.1)
if is_beat:
n_particles = int(current_rms * tempo * 0.5) # 现在current_rms是标量
new_particles = []
for _ in range(n_particles):
is_positive = np.random.rand() > 0.5
freq = current_centroid * (1 if is_positive else -1)
rgb = frequency_to_color(freq, is_positive)
rgba = (*rgb, 1.0)
size = np.clip(np.random.normal(25, 15), 1, 50)
new_particles.append((
np.random.rand(2),
rgba,
size,
np.clip(1.0, 0.0, 1.0)
))
if new_particles:
new_arr = np.array(new_particles, dtype=particle_dtype)
particles = np.concatenate((particles, new_arr))
if particles.size > 0:
particles['alpha'] -= 0.05 * (tempo/120)
valid_mask = particles['alpha'] > 0
particles = particles[valid_mask]
if particles.size > 0:
coll = EllipseCollection(
widths=particles['size'] * pixel_to_norm,
heights=particles['size'] * pixel_to_norm,
angles=np.zeros(len(particles)),
offsets=particles['pos'],
transOffset=ax.transData,
facecolors=particles['color'],
edgecolors='none',
alpha=particles['alpha']
)
ax.add_collection(coll)
if S.size > 0:
current_col = frame_idx % S.shape[1]
for i, arc in enumerate(arcs):
if current_col < S.shape[1]:
freq_energy = S[i % S.shape[0], current_col]
theta = np.clip(freq_energy * 360 / (S.max() or 1), 0, 360)
arc.theta2 = theta
writer.grab_frame()
pbar.update(1)
with tqdm(total=1, desc="合并音视频") as pbar:
subprocess.run([
'ffmpeg', '-y',
'-i', 'temp_video.mp4',
'-i', audio_path,
'-c:v', 'copy',
'-c:a', 'aac',
'-map', '0:v:0',
'-map', '1:a:0',
'-shortest',
output_path
], check=True)
pbar.update(1)
os.remove("temp_video.mp4")
print(f"\n生成完成:{output_path}")
```
**关键修改说明:**
1. **显式标量转换**:
```python
current_rms = rms[frame_idx % len(rms)].item() # 使用.item()转换为Python标量
current_centroid = spectral_centroid[frame_idx % len(spectral_centroid)].item()
```
2. **类型安全运算**:
```python
n_particles = int(current_rms * tempo * 0.5) # 现在所有操作数都是标量类型
```
3. **保持numpy数组特性**:
```python
particles = np.empty(0, dtype=particle_dtype) # 保持结构化数组特性
```
4. **兼容性优化**:
```python
spectral_centroid = librosa.feature.spectral_centroid(...)[0] # 确保获取一维数组
```
阅读全文
相关推荐


















