Commit 0396dd45 authored by martin hou's avatar martin hou

feat: 增加文件传输方法用于持续传输

parent f78e7c8a
---
description:
globs:
alwaysApply: true
---
If there is anything unclear about the task objective, please reject it explicitly. You can supplement the relevant content through secondary inquiry, but you must not use default values ​​or imagine possible solutions.
\ No newline at end of file
......@@ -168,6 +168,9 @@ declare class Jensen {
// 注意:文件传输进度和数据并不是同时到达的,在文件传输到100%时才会开始调用on回调进行转移数据
getFile: (fileName: string, length: number, on?: (msg: Uint8Array | 'fail') => void, onprogress?: (size: number) => void) => void;
// 持续传输文件,filename为文件名称,length为文件长度,ondata为数据回调,seconds为超时时长
transferFile: (filename: string, length: number, ondata: (msg: Uint8Array | 'fail') => void, seconds?: number) => Promise<ReturnStruct['common']>;
// 获取指定长度的录音文件内容,length参数可以小于或等于文件的原始长度,其它参数与getFile()方法一致
getFilePart: (fileName: string, length: number, on?: (msg: Uint8Array | 'fail') => void, onprogress?: (size: number) => void) => void;
......
......@@ -9,6 +9,8 @@
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"@ffmpeg/ffmpeg": "^0.12.15",
"@ffmpeg/util": "^0.12.2",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
......@@ -429,6 +431,33 @@
"node": ">=18"
}
},
"node_modules/@ffmpeg/ffmpeg": {
"version": "0.12.15",
"resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.15.tgz",
"integrity": "sha512-1C8Obr4GsN3xw+/1Ww6PFM84wSQAGsdoTuTWPOj2OizsRDLT4CXTaVjPhkw6ARyDus1B9X/L2LiXHqYYsGnRFw==",
"dependencies": {
"@ffmpeg/types": "^0.12.4"
},
"engines": {
"node": ">=18.x"
}
},
"node_modules/@ffmpeg/types": {
"version": "0.12.4",
"resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.4.tgz",
"integrity": "sha512-k9vJQNBGTxE5AhYDtOYR5rO5fKsspbg51gbcwtbkw2lCdoIILzklulcjJfIDwrtn7XhDeF2M+THwJ2FGrLeV6A==",
"engines": {
"node": ">=16.x"
}
},
"node_modules/@ffmpeg/util": {
"version": "0.12.2",
"resolved": "https://registry.npmjs.org/@ffmpeg/util/-/util-0.12.2.tgz",
"integrity": "sha512-ouyoW+4JB7WxjeZ2y6KpRvB+dLp7Cp4ro8z0HIVpZVCM7AwFlHa0c4R8Y/a4M3wMqATpYKhC7lSFHQ0T11MEDw==",
"engines": {
"node": ">=18.x"
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.28.1",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.28.1.tgz",
......
......@@ -24,6 +24,8 @@
"vite": "^6.0.3"
},
"dependencies": {
"@ffmpeg/ffmpeg": "^0.12.15",
"@ffmpeg/util": "^0.12.2",
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
......
......@@ -50,20 +50,20 @@ const COMMAND_NAMES = {
[DELETE_FILE]: 'delete-file',
[REQUEST_FIRMWARE_UPGRADE]: 'request-firmware-upgrade',
[FIRMWARE_UPLOAD]: 'firmware-upload',
[READ_CARD_INFO]: 'read card info',
[FORMAT_CARD]: 'format card',
[GET_RECORDING_FILE]: 'get recording file',
[RESTORE_FACTORY_SETTINGS]: 'restore factory settings',
[SCHEDULE_INFO]: 'send meeting schedule info',
[DEVICE_MSG_TEST]: 'device msg test',
[BNC_DEMO_TEST]: 'bnc demo test',
[READ_CARD_INFO]: 'read-card-info',
[FORMAT_CARD]: 'format-card',
[GET_RECORDING_FILE]: 'get-recording-file',
[RESTORE_FACTORY_SETTINGS]: 'restore-factory-settings',
[SCHEDULE_INFO]: 'calendar',
[DEVICE_MSG_TEST]: 'test',
[BNC_DEMO_TEST]: 'bnc-demo',
[GET_SETTINGS]: 'get-settings',
[SET_SETTINGS]: 'set-settings',
[GET_FILE_BLOCK]: 'get file block',
[FACTORY_RESET]: 'factory reset',
[TEST_SN_WRITE]: 'test sn write',
[RECORD_TEST_START]: 'record test start',
[RECORD_TEST_END]: 'record test end',
[GET_FILE_BLOCK]: 'get-file-block',
[FACTORY_RESET]: 'factory-reset',
[TEST_SN_WRITE]: 'test-sn-write',
[RECORD_TEST_START]: 'record-test-start',
[RECORD_TEST_END]: 'record-test-end',
[BLUETOOTH_SCAN]: 'bluetooth-scan',
[BLUETOOTH_CMD]: 'bluetooth-cmd',
[BLUETOOTH_STATUS]: 'bluetooth-status'
......@@ -378,13 +378,9 @@ function Jensen(log, conn) {
blocks.push(result.data);
tryReceive();
if (self.decodeTimeout) clearTimeout(self.decodeTimeout);
self.decodeTimeout = setTimeout(function () {
tryDecode();
}, self.timewait);
self.decodeTimeout = setTimeout(function () { tryDecode(); }, self.timewait);
if (self.onreceive) {
try {
self.onreceive(totalBytes);
} catch (e) {}
try { self.onreceive(totalBytes); } catch (e) {}
}
};
......@@ -797,6 +793,27 @@ Jensen.prototype.readFile = async function (filename, offset, length, seconds) {
return this.send(new Command(TRANSFER_FILE_PARTIAL).body(data), seconds);
}
Jensen.prototype.transferFile = async function (filename, length, ondata, seconds) {
let fname = [];
for (let i = 0; i < filename.length; i++) fname.push(filename.charCodeAt(i));
let flen = 0;
this.registerHandler(TRANSFER_FILE, (msg) => {
if (msg != null) {
flen += msg.body.length || msg.body.byteLength;
ondata(msg.body);
Logger.info('jensen', 'transfer-file', `${length} ${flen}`);
if (flen >= length) {
Logger.info('jensen', 'transfer-file', 'file transfer finish.');
return 'OK';
}
} else {
Logger.info('jensen', 'transfer-file', 'file transfer fail.');
ondata('fail');
}
});
return this.send(new Command(TRANSFER_FILE).body(fname), seconds);
}
Jensen.prototype.setTime = async function (time, seconds) {
let str =
time.getFullYear() +
......
......@@ -11,7 +11,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
"target": "es2020" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"jsx": "react-jsx" /* Specify what JSX code is generated. */,
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
......@@ -25,7 +25,7 @@
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
/* Modules */
"module": "commonjs" /* Specify what module code is generated. */,
"module": "es2020" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
......
......@@ -4,5 +4,26 @@ import react from '@vitejs/plugin-react-swc';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
server: { open: true, hmr: true, port: 6300, host: '0.0.0.0' }
server: {
open: true,
hmr: true,
port: 6300,
host: '0.0.0.0',
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
}
},
optimizeDeps: {
exclude: ['@ffmpeg/ffmpeg', '@ffmpeg/util']
},
build: {
rollupOptions: {
output: {
manualChunks: {
ffmpeg: ['@ffmpeg/ffmpeg', '@ffmpeg/util']
}
}
}
}
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment