react-native-sherpa-onnx-offline-stt
Version:
React Native wrapper for sherpa-onnx offline speech-to-text with TEN-VAD and speaker diarization
163 lines (142 loc) • 5.1 kB
JavaScript
const https = require('https');
const fs = require('fs');
const path = require('path');
// Check if running on macOS or iOS build environment
const isMacOS = process.platform === 'darwin';
if (!isMacOS) {
console.log('Skipping iOS framework download on non-macOS platform');
process.exit(0);
}
const SHERPA_VERSION = '1.12.23';
const url = `https://github.com/k2-fsa/sherpa-onnx/releases/download/v${SHERPA_VERSION}/sherpa-onnx-v${SHERPA_VERSION}-ios.tar.bz2`;
const destination = path.join(__dirname, `sherpa-onnx-v${SHERPA_VERSION}-ios.tar.bz2`);
const tarFilePath = path.join(__dirname, `sherpa-onnx-v${SHERPA_VERSION}-ios.tar`);
const extractPath = path.join(__dirname, '..');
// Check if build-ios already exists
const buildIosPath = path.join(extractPath, 'build-ios');
if (fs.existsSync(buildIosPath)) {
const sherpaPath = path.join(buildIosPath, 'sherpa-onnx.xcframework');
if (fs.existsSync(sherpaPath)) {
console.log(`sherpa-onnx v${SHERPA_VERSION} iOS frameworks already exist, skipping download`);
process.exit(0);
}
}
console.log(`Downloading sherpa-onnx v${SHERPA_VERSION} iOS frameworks...`);
function downloadFile(url, destination, callback) {
https
.get(url, (response) => {
// Handle redirects
if (
response.statusCode >= 300 &&
response.statusCode < 400 &&
response.headers.location
) {
console.log(`Redirecting to: ${response.headers.location}`);
return downloadFile(response.headers.location, destination, callback);
}
if (response.statusCode !== 200) {
console.error(`Download failed with status code: ${response.statusCode}`);
process.exit(1);
}
const contentLength = response.headers['content-length'];
let downloaded = 0;
let lastPercent = 0;
const file = fs.createWriteStream(destination);
response.on('data', (chunk) => {
downloaded += chunk.length;
if (contentLength) {
const percent = Math.floor((downloaded / contentLength) * 100);
if (percent !== lastPercent && percent % 10 === 0) {
console.log(`Download progress: ${percent}%`);
lastPercent = percent;
}
}
});
response.pipe(file);
file.on('finish', () => {
file.close(callback);
});
file.on('error', (err) => {
fs.unlink(destination, () => {});
console.error('Error writing to file:', err.message);
process.exit(1);
});
})
.on('error', (err) => {
console.error('Download failed:', err.message);
process.exit(1);
});
}
// Dynamically import unbzip2-stream and tar
async function extractArchive() {
let bz2, tar;
try {
bz2 = require('unbzip2-stream');
tar = require('tar');
} catch (e) {
console.log('Required modules not found. Installing...');
const { execSync } = require('child_process');
execSync('npm install unbzip2-stream tar --no-save', { stdio: 'inherit' });
bz2 = require('unbzip2-stream');
tar = require('tar');
}
return new Promise((resolve, reject) => {
// Step 1: Decompress the .bz2 file to .tar
console.log('Decompressing archive...');
const input = fs.createReadStream(destination);
const output = fs.createWriteStream(tarFilePath);
input
.pipe(bz2())
.pipe(output)
.on('finish', async () => {
try {
// Step 2: Extract the .tar file
console.log('Extracting archive...');
await tar.x({
file: tarFilePath,
cwd: extractPath,
sync: true,
});
// Cleanup the tar.bz2 and .tar files after extraction
fs.unlinkSync(destination);
fs.unlinkSync(tarFilePath);
console.log(
`sherpa-onnx-v${SHERPA_VERSION}-ios downloaded, decompressed, and extracted.`
);
// Verification: Check if 'build-ios' directory exists
if (fs.existsSync(buildIosPath)) {
console.log('Verification successful: build-ios directory exists.');
fs.readdir(buildIosPath, (err, files) => {
if (err) {
console.error('Error reading build-ios directory:', err);
} else {
console.log('Contents of build-ios:', files);
}
resolve();
});
} else {
console.error('Verification failed: build-ios directory is missing.');
reject(new Error('build-ios directory is missing'));
}
} catch (error) {
console.error('Error during extraction:', error);
reject(error);
}
})
.on('error', (error) => {
console.error('Error during decompression:', error);
reject(error);
});
});
}
downloadFile(url, destination, () => {
extractArchive()
.then(() => {
console.log('iOS framework setup complete!');
process.exit(0);
})
.catch((err) => {
console.error('Failed to extract archive:', err);
process.exit(1);
});
});