CocosCreator获取音乐峰值插件

757 阅读1分钟

前言:

音乐节奏类的游戏,音符需要根据节奏生成,cococs自身的api满足不了需求,需要自己开发。

image.png

功能及思路:

image.png

实现点击parsing-audio,将该项目audio目录下的.mp3的峰值获取,写入到.json文件中,方便游戏中读取使用。

依赖于python的librosa库分析音频,编写cocos扩展插件,实现一键生成峰值.json文件。

关键代码:

main.py

#coding=utf-8
import librosa
import os
import json
import numpy as np


def save_data(data):
    #跳转resources目录下
    path = os.path.abspath('../..') + '/assets/resources'
    os.chdir( path )
    f=open("level.json","w")
    f.write(json.dumps(data))
    f.close()

def analysis(nameKey,path,configJosn):
    y, sr = librosa.load(path)
    tempo, beat_frames = librosa.beat.beat_track(y=y, sr=sr)

    #获取音乐时间
    musicTimer=librosa.get_duration(filename=path)
    #将时间转化为帧数
    musicFrame=librosa.time_to_frames(musicTimer)
    #获取每个节拍平均相隔几帧   每首歌的节拍是大概固定的
    beatsDis=musicFrame/len(beat_frames)

    # 峰值点 帧数
    onset_env = librosa.onset.onset_strength(y=y, sr=sr,hop_length=512,aggregate=np.median)
    peaks = librosa.util.peak_pick(onset_env, 3, 3,3, 5, 0.5, 12)
    peaks_to_timer= librosa.frames_to_time(peaks, sr=sr)

    dataStr="[0,"
    for item in peaks_to_timer:
            dataStr=dataStr+str(item)+","
    dataStr=dataStr[:len(dataStr)-1]
    dataStr=dataStr+"]"

    json={}
    json["timer"]=musicTimer
    json["rhythm"]=dataStr
    configJosn[nameKey]=json

def getFileList(configJosn):
    # 指定目录
    basePath = os.path.abspath('../..') + '/assets/audio'
    audioList = os.listdir(basePath)
    print(audioList)

    for tmp in audioList:
            audioPath = os.path.join(basePath, tmp)
            if audioPath.endswith('.mp3'):
                    name=tmp[:tmp.find('.mp3')]
                    print("print "+audioPath+" audio datas----")
                    analysis(name,audioPath,configJosn)

if __name__=="__main__":
	configJosn={}
	getFileList(configJosn)
	save_data(configJosn)

main.js文件

"use strict";
//引入命令行
const exec = require("child_process").exec; 
module.exports = {
  messages: {
    open() {
      var cmdStr = "python main.py";
      Editor.log("正在生成节奏...")
      exec(cmdStr, {cwd: __dirname},function (err, stdout, stderr) {
        if (err) {
          Editor.log("error:" + stderr);
        } else {
          Editor.log("音乐节奏生成" + stdout);
        }
      });
    },
  },
};

//exec0(要执行的CMD命令, {cwd: "工作目录"},(error,stdout,stderr) => {})