Skip to content

Commit

Permalink
add msedge tts to generate audio for simplified
Browse files Browse the repository at this point in the history
  • Loading branch information
krmanik committed Feb 11, 2024
1 parent ce3aea9 commit 786b38c
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 15 deletions.
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@docusaurus/preset-classic": "^3.1.1",
"@mdx-js/react": "^1.6.22",
"buffer": "^6.0.3",
"bufferutil": "^4.0.8",
"chinese-s2t": "^1.0.0",
"chinese-to-pinyin": "^1.3.1",
"clsx": "^1.2.1",
Expand All @@ -29,9 +30,11 @@
"genanki-js": "^2.0.0",
"hanzi-writer": "^3.3.0",
"jieba-wasm": "^0.0.2",
"msedge-tts": "^1.3.4",
"path-browserify": "^1.0.1",
"primereact": "^10.5.0",
"prism-react-renderer": "^1.3.5",
"process": "^0.11.10",
"react": "^18.1.0",
"react-dom": "^18.1.0",
"react-icons": "^4.4.0",
Expand All @@ -40,7 +43,9 @@
"sql.js": "^1.10.2",
"stream-browserify": "^3.0.0",
"unzipit": "^1.4.3",
"url-loader": "^4.1.1"
"url-loader": "^4.1.1",
"utf-8-validate": "^6.0.3",
"webpack": "^5.90.1"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.1.1",
Expand Down
9 changes: 9 additions & 0 deletions plugins/custom-docusaurus-plugin/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const webpack = require('webpack');

module.exports = function (context, options) {
return {
name: 'custom-docusaurus-plugin',
Expand All @@ -12,11 +14,18 @@ module.exports = function (context, options) {
crypto: require.resolve("crypto-browserify"),
buffer: require.resolve("buffer/"),
stream: require.resolve("stream-browserify"),
process: "process/browser",
},
fallback: {
fs: false,
ws: false,
}
},
plugins: [
new webpack.ProvidePlugin({
process: 'process/browser'
})
]
};
},
};
Expand Down
2 changes: 1 addition & 1 deletion src/dict/dict.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { unzip } from 'unzipit';
import pinzhu from './pinyinzhuyin';

let dict;
let host = "http://localhost:3000/Anki-xiehanzi/";
let host = "https://krmanik.github.io/Anki-xiehanzi";

// https://github.com/cschiller/zhongwen
class ZhongwenDictionary {
Expand Down
79 changes: 71 additions & 8 deletions src/pages/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ import pinzhu from "../dict/pinyinzhuyin";
import create_styles from "./create.module.css";
import styles from "./index.module.css";

import { MsEdgeTTS, OUTPUT_FORMAT } from "msedge-tts";
import { ProgressBar } from "primereact/progressbar";

export default function CreateDeck(): JSX.Element {
const [words, setWords] = useState<
{
Expand Down Expand Up @@ -62,6 +65,7 @@ export default function CreateDeck(): JSX.Element {
const [texAreaValue, setTexAreaValue] = React.useState<string>("");
const [db, setDb] = useState(null);
const dt = useRef(null);
const [progressbarValue, setProgressbarValue] = useState(0);

const exportCSV = (selectionOnly) => {
dt.current.exportCSV({ selectionOnly });
Expand Down Expand Up @@ -454,6 +458,26 @@ export default function CreateDeck(): JSX.Element {
setWords([...words, ..._words]);
}

// https://github.com/feross/stream-to-blob/blob/master/index.js
function streamToBlob(stream, mimeType): Promise<Blob> {
if (mimeType != null && typeof mimeType !== "string") {
throw new Error("Invalid mimetype, expected string.");
}
return new Promise((resolve, reject) => {
const chunks = [];
stream
.on("data", (chunk) => chunks.push(chunk))
.once("end", () => {
const blob =
mimeType != null
? new Blob(chunks, { type: mimeType })
: new Blob(chunks);
resolve(blob);
})
.once("error", reject);
});
}

async function generateDeck(e) {
let flds = [];
let req = [];
Expand Down Expand Up @@ -582,11 +606,11 @@ for (var _hide of hideList) {
});
}

const modelId = Math.floor(Math.random() * (1 << 30) + (1 << 30));
// const modelId = Math.floor(Math.random() * (1 << 30) + (1 << 30));

const m = new Model({
name: "Basic - (Anki-xiehanzi)",
id: modelId.toString(),
id: "1969669503",
flds: flds,
css: CONSTANTS.DECK_CSS,
req: req,
Expand Down Expand Up @@ -688,22 +712,59 @@ for (var _hide of hideList) {
if (!response.ok) {
return null;
}

progress += 1;
setProgressbarValue((progress / total) * 100);

return response.blob();
};

Promise.all(mediaFiles.map(fetchFile))
const wordFiles = words.map((word) => word.Simplified);

let progress = 0;
let total = wordFiles.length + mediaFiles.length;

const fetchAudio = async (word) => {
const tts = new MsEdgeTTS();
await tts.setMetadata(
"zh-CN-XiaoxiaoNeural",
OUTPUT_FORMAT.AUDIO_24KHZ_48KBITRATE_MONO_MP3
);
const readable = tts.toStream(word);
const blob = await streamToBlob(readable, "audio/mp3");

progress += 1;
setProgressbarValue((progress / total) * 100);

return blob;
};

// edge tts mp3 audio
Promise.all(wordFiles.map(fetchAudio))
.then((blobs) => {
blobs.forEach((blob, index) => {
if (blob) {
p.addMedia(blob, mediaFiles[index]);
}
p.addMedia(blob, `cmn-${wordFiles[index]}.mp3`);
});
})
.catch((error) => {
console.error("Error fetching or adding media:", error);
})
.finally(() => {
p.writeToFile(`${deckName}.apkg`);
.finally(async () => {
// sidebar icons
Promise.all(mediaFiles.map(fetchFile))
.then((blobs) => {
blobs.forEach((blob, index) => {
if (blob) {
p.addMedia(blob, mediaFiles[index]);
}
});
})
.catch((error) => {
console.error("Error fetching or adding media:", error);
})
.finally(async () => {
p.writeToFile(`${deckName}.apkg`);
});
});
}

Expand Down Expand Up @@ -905,6 +966,8 @@ for (var _hide of hideList) {
</div>
)}

<ProgressBar value={progressbarValue}></ProgressBar>

<div className={`${styles.button_bar}`}>
<Toolbar
start={
Expand Down
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"extends": "@tsconfig/docusaurus/tsconfig.json",
"compilerOptions": {
"jsx": "react",
"baseUrl": "."
"baseUrl": ".",
"esModuleInterop": true,
}
}
Loading

0 comments on commit 786b38c

Please sign in to comment.