Node.js 16.xからNode.js 18.xにコード変更したら動作しない

留守番電話を実装するため、下記参考サイトのWAV形式に変換してS3に保存するLambdaを利用して、問題なく動作しておりましたが、Node.js 16.xからNode.js 18.xにコード変更したところ、WAVファイルは作成されますが、中身が0バイトとなり、再生することができません。

参考サイト:https://qiita.com/echolimitless/items/af068e147e233c51d6a4

-------------------------Node.js 18.xコード---------------------------------------------------

const region = 'ap-northeast-1';
const putKey = 'wav/';
const bucketName = 'my-baseXXXXXXXXX';

// S3インポート
import { GetObjectCommand, PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
// Amazon Kinesis Videoインポート
import { KinesisVideoClient, GetDataEndpointCommand } from "@aws-sdk/client-kinesis-video";
// Amazon Kinesis Video mediaインポート
import { KinesisVideoMediaClient, GetMediaCommand } from "@aws-sdk/client-kinesis-video-media";
const kvmClient = new KinesisVideoMediaClient({ region : region });
import ebml from 'ebml';
console.log(===ebml===:${ebml});

export const handler = async (event) => {

console.log(JSON.stringify(event)); const region = 'ap-northeast-1'; const s3Client = new S3Client({ region: region }); for (let record of event.Records) { // information/yyyymmdd_×××をgetKeyに格納 const getKey = record.s3.object.key; // '/'までの文字数10がindexに格納 let index = getKey.lastIndexOf('/'); let fileName = 'noname'; if (index >= 0) { // getKeyに対して、文字数11以降("/")の文字列を取得 fileName = getKey.substr(index + 1); } // S3から録音データに関する情報を取得 const s3GetCommand = new GetObjectCommand({ Bucket: bucketName, Key: getKey }); const s3GetRes = await s3Client.send(s3GetCommand); const info = await s3GetRes.Body.transformToString(); const infoStr = JSON.parse(info); console.log(`==info==:${info}`); console.log(`==infoStr==:${infoStr}`); const streamName = infoStr.streamARN.split('stream/')[1].split('/')[0]; const fragmentNumber = infoStr.startFragmentNumber; const streamARN = infoStr.streamARN; console.log(`==streamName==:${streamName}`); console.log(`==fragmentNumber==:${fragmentNumber}`); // Kinesis Video StreamsからRAWデータの取得 const kvmInput = { StreamName: streamName, StreamARN: streamARN, StartSelector: { StartSelectorType: fragmentNumber, }, }; const kvmCommand = new GetMediaCommand(kvmInput); const data = await kvmClient.send(kvmCommand); // Kinesis Video StreamsからRAWデータの取得 const raw = await getMedia(streamName, fragmentNumber); // RAWデータからWAVファイルを作成 const wav = Converter.createWav(raw, 8000); // WAVファイルをS3に保存 let tagging = ''; // 付加情報をタグに追加する tagging += "customerEndpoint=" + info.customerEndpoint + '&'; tagging += "systemEndpoint=" + info.systemEndpoint + '&'; tagging += "startTimestamp=" + info.startTimestamp; // await s3.put(bucketName, putKey + createKeyName() + fileName + '.wav', Buffer.from(wav.buffer), tagging) const wavInput = new PutObjectCommand({ Bucket: bucketName, Key: putKey + createKeyName() + fileName + '.wav', Body: Buffer.from(wav.buffer), Tag: tagging }); const wavRes = await s3Client.send(wavInput); } // for

}; // export const handler

// S3バケット保存時のオブジェクト名を生成
function createKeyName() {

const date = new Date(); const year = date.getFullYear(); const mon = (date.getMonth() + 1); const day = date.getDate(); const hour = date.getHours(); const space = (n) => { console.log(`==n==${n}`); return ('0' + (n)).slice(-2); }; let result = year + '/'; result += space(mon) + '/'; result += space(day) + '/'; result += space(hour) + '/'; return result;

} // createKeyName

// ebml「on」のインポート
let chunks = [];
let decoder = function () {};
function decoderOn() {
decoder.on = function (data, chunk) {
if(chunk[1].name == 'SimpleBlock'){
chunks.push(chunk[1].data);
}

for(let chunk of chunks){ if(chunk[1].name == 'SimpleBlock'){ chunks.push(chunk[1].data); } } return chunk; };

}

// export default decoderOn;
decoderOn();

console.log(==decoder==${decoder});

// 録音データの取得・wavデータへの変換
async function getMedia(streamName, fragmentNumber) {
// Endpointの取得
let kvInput = {
APIName: "GET_MEDIA",
StreamName: streamName
};

const kvClient = new KinesisVideoClient({ region : region }); const kvCommand = new GetDataEndpointCommand(kvInput); const end = await kvClient.send(kvCommand); // RAWデータの取得 let kvmInput = { StartSelector: { StartSelectorType: "FRAGMENT_NUMBER", AfterFragmentNumber:fragmentNumber, }, StreamName: streamName }; const kvmClient = new KinesisVideoMediaClient({ endpoint: end.DataEndpoint, region : region }); const kvmCommand = new GetMediaCommand(kvmInput); const data = await kvmClient.send(kvmCommand); console.log('==chunks=='); console.log(chunks); // ebml「write」へのインポート function decoderWrite() { decoder.write = function () { decoder.write(data["Payload"]); return data; }; } // export default decoderWrite(); decoderWrite(); console.log('==chunks2=='); console.log(chunks); // chunksの結合 const margin = 4; // 各chunkの先頭4バイトを破棄する var sumLength = 0; chunks.forEach( chunk => { sumLength += chunk.byteLength - margin; }); var sample = new Uint8Array(sumLength); var pos = 0; chunks.forEach(chunk => { let tmp = new Uint8Array(chunk.byteLength - margin); for(var e = 0; e < chunk.byteLength - margin; e++){ tmp[e] = chunk[e + margin]; } sample.set(tmp, pos); pos += chunk.byteLength - margin; }); console.log('==sample=='); console.log(sample); return sample.buffer;

} // async function getMedia

class Converter {
// WAVファイルの生成
static createWav(samples, sampleRate) {
const len = samples.byteLength;
const view = new DataView(new ArrayBuffer(44 + len));
this._writeString(view, 0, 'RIFF');
view.setUint32(4, 32 + len, true);
this._writeString(view, 8, 'WAVE');
this._writeString(view, 12, 'fmt ');
view.setUint32(16, 16, true);
view.setUint16(20, 1, true); // リニアPCM
view.setUint16(22, 1, true); // モノラル
view.setUint32(24, sampleRate, true);
view.setUint32(28, sampleRate * 2, true);
view.setUint16(32, 2, true);
view.setUint16(34, 16, true);
this._writeString(view, 36, 'data');
view.setUint32(40, len, true);
let offset = 44;
const srcView = new DataView(samples);
for (var i = 0; i < len; i+=4, offset+=4) {
view.setInt32(offset, srcView.getUint32(i));
}
return view;
}

static _writeString(view, offset, string) { for (var i = 0; i < string.length; i++) { view.setUint8(offset + i, string.charCodeAt(i)); } }

} // class Converter

コメントを投稿

0 コメント