Skip to content

Commit

Permalink
add vrx support
Browse files Browse the repository at this point in the history
  • Loading branch information
MOTOO11 committed Dec 8, 2016
1 parent 16a9564 commit 04d4e8d
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 25 deletions.
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## liveport - live broadcast support tool.
したらば掲示板・CaveTubeのコメントを、ブラウザ上に表示・読み上げ(v1.0.0)
したらば掲示板・CaveTubeのコメントを、ブラウザ上に表示・読み上げ
### [download](https://github.com/odangosan/liveport/releases)
### 使い方
* liveport.exeを起動
Expand All @@ -18,12 +18,23 @@
* background-color: rgba(0, 0, 0, 0); 背景透過(必須)
* overflow: hidden; 長い文章を途中で省略する(必須)
* color:white; 文字の色(変更可能)
* タイトルバーにURLを入力後、**[]読み込み開始**ボタンを押す
* タイトルバーにURLを入力後、**[]読み込み開始**ボタンを押す
* 詳細な設定は[resources/app/config.json]
* NGワード・読み替えなど

* データは以下に保存される
* データは以下に保存
* C:\Users\%USERNAME%\AppData\Roaming\liveport\
*

### 対応しているURL
* したらば[http://jbbs.shitaraba.net/bbs/read.cgi/[ジャンル]/[掲示板ID]/[スレッドID]/]
* CaveTube[https://www.cavelis.net/live/[配信名]]

### 読み上げボイスを変える
* デフォルトの[WSA]を使うためには
* [Microsoft Server Speech Text to Speech Voice (ja-JP, Haruka)]のインストールが必要です
* sofTalkを使う場合は[Softalk/vrsのパス]でSofTalk.exeを選択する
* 民安Talkを使う場合は[Softalk/vrsのパス]でvrx.exeを選択する
* ※民安Talkを使う場合、読み上げ時間制限の設定値により民安Talkに送られる文章が途中で省略される場合があります

* ver 1.0.0
* 初版
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "liveport",
"version": "1.0.2",
"version": "1.1.0",
"description": "livestream support tool",
"main": "build/main.js",
"scripts": {
Expand Down
10 changes: 7 additions & 3 deletions src/renderer/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<nav class="mdl-navigation">
<span class="mdl-navigation__link">
<label><i class="material-icons">refresh</i> リロード:{{reload}}</label>
<input class="mdl-slider mdl-js-slider" type="range" max="60" min="7" v-model="reload" v-bind:disabled="processing" />
<input class="mdl-slider mdl-js-slider" type="range" max="60" min="10" v-model="reload" v-bind:disabled="processing" />
</span>
<span class="mdl-navigation__link">
<label><i class="material-icons">record_voice_over</i> 読み上げ</label>
Expand All @@ -47,7 +47,7 @@
</span>
<span class="mdl-navigation__link">
<label><i class="material-icons">timer</i> 読み上げ時間制限:{{provideTimeLimit}}</label>
<input class="mdl-slider mdl-js-slider" type="range" max="60" min="3" v-model="provideTimeLimit" v-bind:disabled="processing" />
<input class="mdl-slider mdl-js-slider" type="range" max="60" min="10" v-model="provideTimeLimit" v-bind:disabled="processing" />
</span>
<span class="mdl-navigation__link">
<label><i class="material-icons">mic</i> 読み上げボイス</label><br>
Expand All @@ -59,9 +59,13 @@
<input type="radio" id="option-2" class="mdl-radio__button" v-model="pManager.voice" v-bind:value="2" v-bind:disabled="processing">
<span class="mdl-radio__label">SofTalk</span>
</label>
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="option-3">
<input type="radio" id="option-3" class="mdl-radio__button" v-model="pManager.voice" v-bind:value="3" v-bind:disabled="processing">
<span class="mdl-radio__label">民安talk</span>
</label>
</span>
<span class="mdl-navigation__link">
<label><i class="material-icons">find_in_page</i> softalkのパス</label>
<label><i class="material-icons">find_in_page</i> softalk/vrxのパス</label>
<div class="mdl-textfield mdl-js-textfield">
<input class="mdl-textfield__input" v-on:click="findSofTalkPathDialog()" id="path" autocomplete="off" v-model="path" v-bind:disabled="processing">
</div>
Expand Down
9 changes: 6 additions & 3 deletions src/renderer/ts/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export default class Application extends Vue {
let letter = tmpLetter.length > 1 ?
tmpLetter[0] + target.num + tmpLetter[1]
: target.num.toString();
this.pManager.provide(letter + ":", target.text, this.pManager.reading);
this.pManager.provide(letter + ":", target.text, this.pManager.reading, this.startProvide, this.provideTimeLimit);
this.thread.next();
if (this.autoScroll)
this.scrollTo(this.thread.bookmark);
Expand Down Expand Up @@ -146,7 +146,7 @@ export default class Application extends Vue {
}

validate(): boolean {
if (this.pManager.voice === VOICE.SOFTALK && this.path === "" && this.pManager.reading && this.processing === true) {
if (this.usePath() && this.path === "" && this.pManager.reading && this.processing === true) {
let warn = {
message: "ERROR : pathが設定されていません。"
}
Expand All @@ -161,6 +161,9 @@ export default class Application extends Vue {
return true;
}

usePath():boolean{
return this.pManager.voice === VOICE.SOFTALK || this.pManager.voice === VOICE.TAMIYASU;
}
// refresh
requestOnce() {
if (!this.validate()) {
Expand Down Expand Up @@ -243,7 +246,7 @@ export default class Application extends Vue {
}

test(letter: string, body: string) {
this.pManager.provide(letter, body, this.pManager.reading);
this.pManager.provide(letter, body, this.pManager.reading,null,this.provideTimeLimit);
}

autoScroll: boolean = false;
Expand Down
17 changes: 13 additions & 4 deletions src/renderer/ts/ProvideManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import SofTalk from "./SofTalk"
import WebspeechApi from "./WebspeechApi"
import Tamiyasu from "./Tamiyasu"
import { VOICE, VoiceParameter } from "./Voice"
import * as io from "socket.io-client";
import StringUtil from "./StringUtil";
Expand Down Expand Up @@ -28,7 +29,7 @@ export default class ProvideManager {
if (this.containsNg(body)) {
const ng = () => {
if (reading) {
this.speaker.speak(letter + "\n" + CONFIG.SystemDictionary.NG.reading, this.vParam, callback);
this.speak(letter + "\n" + CONFIG.SystemDictionary.NG.reading, callback,timeLimit);
}
this.socket.emit(MODE.MESSAGE, letter + "\r\n" + CONFIG.SystemDictionary.NG.reading);
}
Expand All @@ -44,7 +45,7 @@ export default class ProvideManager {
let brReplace = StringUtil.replaceBr2NewLine(anchorReplace);
const aa = () => {
if (reading)
this.speaker.speak(letter + "\n" + SystemDictionary.AA.reading, this.vParam, callback);
this.speak(letter + "\n" + SystemDictionary.AA.reading, callback,timeLimit);
this.socket.emit(MODE.AA, letter + "\r\n" + brReplace);
}

Expand All @@ -65,7 +66,7 @@ export default class ProvideManager {
let urlReplace = StringUtil.urlToReadable(brReplace);
let userDictionary = StringUtil.applyUserDictionary(urlReplace);
let ZENHANReplace = StringUtil.replaceHANKAKUtoZENKAKU(userDictionary);
this.speaker.speak(letter + "\n" + ZENHANReplace, this.vParam, callback);
this.speak(letter + "\n" + ZENHANReplace, callback,timeLimit);
}
this.socket.emit(MODE.MESSAGE, letter + "\r\n" + brReplace);
}
Expand All @@ -76,7 +77,13 @@ export default class ProvideManager {
messenger();
}
}

speak(body: string, callback?: () => any, timeLimit?: number) {
let text = body;
if (this.voice === VOICE.TAMIYASU) {
text = Tamiyasu.calcStringSize(body,timeLimit);
}
this.speaker.speak(text, this.vParam, callback);
}
containsNg(text: string): boolean {
return StringUtil.containsNg(text);
}
Expand All @@ -95,6 +102,8 @@ export default class ProvideManager {
this.speaker = new WebspeechApi();
} else if (value === VOICE.SOFTALK) {
this.speaker = new SofTalk(path);
} else if (value === VOICE.TAMIYASU) {
this.speaker = new Tamiyasu(path);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/renderer/ts/SofTalk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ class SofTalk implements Speaker {
// SofTalkは読み上げ終了を検知出来ない
speak(text: string, vParam: VoiceParameter, callback?: () => any) {
var args = "";
args += " /V:" + (vParam.use ? vParam.adjustmentVolume(0, 100) : defaultParameter.volume);
args += " /S:" + (vParam.use ? vParam.adjustmentRate(1, 300) : defaultParameter.rate);
args += " /O:" + (vParam.use ? vParam.adjustmentPitch(1, 300) : defaultParameter.pitch);
if (vParam.use) args += " /V:" + vParam.adjustmentVolume(0, 100);
if (vParam.use) args += " /S:" + vParam.adjustmentRate(1, 300);
if (vParam.use) args += " /O:" + vParam.adjustmentPitch(1, 300);
args += " /W:" + text.replace(/\n/gi, " ");

// console.log(this.path +" " +args);
Expand Down
43 changes: 43 additions & 0 deletions src/renderer/ts/Tamiyasu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as cp from "child_process";
import * as os from "os";
import Logger from "./Logger";
import { VoiceParameter } from "./Voice"
import { Speaker } from "./Speaker"
const defaultParameter = {
volume: 50,
rate: 100,
pitch: 100
}
class Tamiyasu implements Speaker {
path: string = "";
constructor(path: string) {
this.path = path;
}
// Tamiyasuは読み上げ終了を検知出来ない
speak(text: string, vParam: VoiceParameter, callback?: () => any) {
var args = text.replace(/\n/gi, " ");
cp.spawn(this.path, [args]).on("exit", (code) => {
Logger.log("result", code);
}).on("error", (err) => {
Logger.log("result", err.name);
process.exit(1);
});
}

cancel() {
// var args = " /stop_now";
// cp.exec(this.path + args, (e, s) => {
// console.log(s);
// });
}
speaking() {
return false;
}

public static calcStringSize(text: string, timeLimit: number) {
let limitSize = timeLimit * readPerSecondWord;
return text.substring(0, limitSize);
}
}
const readPerSecondWord = 4;
export default Tamiyasu;
2 changes: 1 addition & 1 deletion src/renderer/ts/Voice.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict"
export enum VOICE {
WSA = 1, SOFTALK = 2
WSA = 1, SOFTALK = 2, TAMIYASU = 3
}
const MAX_RATE = 1.8;
"use strict"
Expand Down
12 changes: 6 additions & 6 deletions src/renderer/ts/WebSpeechApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ class WebSpeechApi implements Speaker {
// 音程 min 0 ~ max 2
this.speech.pitch = vParam.use ? vParam.adjustmentPitch(0, 2) : defaultParameter.pitch;
this.speech.text = text;
if (callback)
this.speech.onend = callback;
// if (callback)
// this.speech.onend = callback;
speechSynthesis.speak(this.speech);
}

cancel() {
var callback = () => {
console.log("overwrite onend callback");
}
this.speech.onend = callback;
// var callback = () => {
// console.log("cancel");
// }
// this.speech.onend = callback;
speechSynthesis.cancel();
}

Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"src/renderer/ts/Logger.ts",
"src/renderer/ts/ProvideManager.ts",
"src/renderer/ts/SofTalk.ts",
"src/renderer/ts/Tamiyasu.ts",
"src/renderer/ts/Speaker.ts",
"src/renderer/ts/StringUtil.ts",
"src/renderer/ts/Shitaraba.ts",
Expand Down

0 comments on commit 04d4e8d

Please sign in to comment.