
留守番電話を実装するため、下記参考サイトのWAV形式に変換してS3に保存するLambdaを利用して、問題なく動作しておりましたが、Node.js 16.xからNode.js 18.xにコード変更したところ、WAVファイルは作成されますが、中身が0バイトとなり、再生することができません。
参考サイト:https://qiita.com/echolimitless/items/af068e147e233c51d6a4
-------------------------Node.js 18.xコード---------------------------------------------------
import { GetObjectCommand, PutObjectCommand, S3Client } from "@aws-sdk/client-s3"; import { KinesisVideoClient, GetDataEndpointCommand } from "@aws-sdk/client-kinesis-video"; import { KinesisVideoMediaClient, GetMediaCommand } from "@aws-sdk/client-kinesis-video-media"; // リージョンやバケット名の設定 const region = 'ap-northeast-1'; const putKey = 'voice-message/wav/'; const bucketName = 'testname-pjcode'; // Lambda関数のエントリーポイント export const handler = async (event) => { // S3クライアントを作成 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); const streamName = infoStr.streamARN.split('stream/')[1].split('/')[0]; const fragmentNumber = infoStr.startFragmentNumber; const streamARN = infoStr.streamARN; // Kinesis Video Media Clientを作成して、録音データを取得 const kvmClient = new KinesisVideoMediaClient({ region : region }); const kvmInput = { StreamName: streamName, StreamARN: streamARN, StartSelector: { StartSelectorType: 'FRAGMENT_NUMBER', AfterFragmentNumber: fragmentNumber, }, }; const kvmCommand = new GetMediaCommand(kvmInput); const data = await kvmClient.send(kvmCommand); // デコードされたデータをWAV形式に変換 const wav = Converter.createWav(data.Payload, 8000); // WAVファイルをS3に保存 let tagging = ''; // 付加情報をタグに追加する tagging += "customerEndpoint=" + infoStr.customerEndpoint + '&'; tagging += "systemEndpoint=" + infoStr.systemEndpoint + '&'; tagging += "startTimestamp=" + infoStr.startTimestamp; const wavInput = new PutObjectCommand({ Bucket: bucketName, Key: putKey + createKeyName() + fileName + '.wav', Body: Buffer.from(wav.buffer), Tagging: tagging }); const wavRes = await s3Client.send(wavInput); } }; // 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) => { return ('0' + (n)).slice(-2); }; let result = year + '/'; result += space(mon) + '/'; result += space(day) + '/'; result += space(hour) + '/'; return result; } // Decoderの初期化 let chunks = []; let decoder = function (data, fragmentNumber) {}; // デコーダー関数の宣言 decoderOn(); // decoderOn関数の呼び出し // デコーダー関数 decoder = function (data, fragmentNumber) { // ここでデコード処理を行う return data.Payload; // 今回はデータそのものを返す }; function decoderOn() { // デコーダーのオン/オフの設定 } class Converter { // WAVファイルの生成 static createWav(samples, sampleRate) { const len = samples.length; const view = new DataView(new ArrayBuffer(44 + len)); this._writeString(view, 0, 'RIFF'); view.setUint32(4, 36 + len, true); // RIFFのサイズを修正 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); for (let i = 0; i < len; i++) { view.setUint8(44 + i, samples[i]); } return view; } static _writeString(view, offset, string) { if (offset + string.length > view.byteLength) { throw new RangeError('Offset is outside the bounds of the DataView'); } for (let i = 0; i < string.length; i++) { if (offset + i < view.byteLength) { view.setUint8(offset + i, string.charCodeAt(i)); } else { throw new RangeError('Offset is outside the bounds of the DataView'); } } } }







あなたの回答
tips
プレビュー