背景
相信我們大家在剛開(kāi)始學(xué)習(xí)一門(mén)語(yǔ)言的時(shí)候都有過(guò)聽(tīng)寫(xiě)费就,現(xiàn)在的小學(xué)生學(xué)語(yǔ)文的時(shí)候一項(xiàng)重要的課后作業(yè)就是聽(tīng)寫(xiě)課文中的生詞,很多家長(zhǎng)們都有這方面的經(jīng)歷川队。不過(guò)一方面這種讀單詞的動(dòng)作相對(duì)簡(jiǎn)單力细,另一方面家長(zhǎng)的時(shí)間也很寶貴,現(xiàn)在市場(chǎng)上出現(xiàn)了很多xx課后聽(tīng)寫(xiě)的語(yǔ)音固额,這些播講人將語(yǔ)文教材上的課后聽(tīng)寫(xiě)單詞錄好眠蚂,給家長(zhǎng)下載使用,不過(guò)這種錄音不夠靈活斗躏,如果老師今天額外留了幾道不是課后習(xí)題中的單詞逝慧,這部分的錄音就不能滿足家長(zhǎng)和孩子們的需要。本文就介紹了一個(gè)使用我們ML kit 的通用文本識(shí)別功能和語(yǔ)音合成功能共同實(shí)現(xiàn)自動(dòng)語(yǔ)音播報(bào)APP啄糙,只需要對(duì)聽(tīng)寫(xiě)的單詞或者課文拍照笛臣,然后就能自動(dòng)播報(bào)照片中的文字,播報(bào)的音色隧饼、音調(diào)都可以調(diào)整沈堡。
開(kāi)發(fā)前準(zhǔn)備
打開(kāi)AndroidStudio項(xiàng)目級(jí)build.gradle文件
在allprojects ->repositories里面配置HMS SDK的maven倉(cāng)地址
allprojects {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'}
}
}
在buildscript->repositories里面配置HMS SDK的maven倉(cāng)地址
buildscript {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'}
}
}
在buildscript->repositories里面配置HMS SDK的maven倉(cāng)地址
buildscript {
repositories {
google()
jcenter()
maven {url 'http://developer.huawei.com/repo/'}
}
}
在buildscript->dependencies中,配置AGC插件
dependencies {
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
}
添加編譯依賴
打開(kāi)應(yīng)用級(jí)的build.gradle文件
集成SDK
dependencies{
implementation 'com.huawei.hms:ml-computer-voice-tts:1.0.4.300'
implementation 'com.huawei.hms:ml-computer-vision-ocr:1.0.4.300'
implementation 'com.huawei.hms:ml-computer-vision-ocr-cn-model:1.0.4.300'
}
應(yīng)用ACG插件燕雁,添加在文件頭即可
apply plugin: 'com.huawei.agconnect'
指定權(quán)限和特性:在AndroidManifest.xml中進(jìn)行聲明
private static final int PERMISSION_REQUESTS = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
// Checking camera permission
if (!allPermissionsGranted()) {
getRuntimePermissions();
}
}
作業(yè)朗讀代碼關(guān)鍵步驟
主要有兩個(gè)功能诞丽,一個(gè)是識(shí)別作業(yè)文本鲸拥,一個(gè)是朗讀作業(yè),通過(guò)OCR+TTS實(shí)現(xiàn)作業(yè)朗讀僧免,拍照后點(diǎn)擊播放即可朗讀刑赶。
1.動(dòng)態(tài)權(quán)限申請(qǐng)
private static final int PERMISSION_REQUESTS = 1;
@Override
public void onCreate(Bundle savedInstanceState) {
// Checking camera permission
if (!allPermissionsGranted()) {
getRuntimePermissions();
}
}
2.啟動(dòng)朗讀界面
public void takePhoto(View view) {
Intent intent = new Intent(MainActivity.this, ReadPhotoActivity.class);
startActivity(intent);
}
3.在onCreate()法中調(diào)用createLocalTextAnalyzer()創(chuàng)建端側(cè)文本識(shí)別器
private void createLocalTextAnalyzer() {
MLLocalTextSetting setting = new MLLocalTextSetting.Factory()
.setOCRMode(MLLocalTextSetting.OCR_DETECT_MODE)
.setLanguage("zh")
.create();
this.textAnalyzer = MLAnalyzerFactory.getInstance().getLocalTextAnalyzer(setting);
}
4.在onCreate()法中調(diào)用createTtsEngine ()創(chuàng)建語(yǔ)音合成引擎,并構(gòu)建語(yǔ)音合成回調(diào)懂衩,用于處理語(yǔ)音合成結(jié)果撞叨,將語(yǔ)音合成回調(diào)傳入新建的語(yǔ)音合成引擎中
private void createTtsEngine() {
MLTtsConfig mlConfigs = new MLTtsConfig()
.setLanguage(MLTtsConstants.TTS_ZH_HANS)
.setPerson(MLTtsConstants.TTS_SPEAKER_FEMALE_ZH)
.setSpeed(0.2f)
.setVolume(1.0f);
this.mlTtsEngine = new MLTtsEngine(mlConfigs);
MLTtsCallback callback = new MLTtsCallback() {
@Override
public void onError(String taskId, MLTtsError err) {
}
@Override
public void onWarn(String taskId, MLTtsWarn warn) {
}
@Override
public void onRangeStart(String taskId, int start, int end) {
}
@Override
public void onEvent(String taskId, int eventName, Bundle bundle) {
if (eventName == MLTtsConstants.EVENT_PLAY_STOP) {
if (!bundle.getBoolean(MLTtsConstants.EVENT_PLAY_STOP_INTERRUPTED)) {
Toast.makeText(ReadPhotoActivity.this.getApplicationContext(), R.string.read_finish, Toast.LENGTH_SHORT).show();
}
}
}
};
mlTtsEngine.setTtsCallback(callback);
}
5.設(shè)置讀取照片、拍照和朗讀按鈕
this.relativeLayoutLoadPhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ReadPhotoActivity.this.selectLocalImage(ReadPhotoActivity.this.REQUEST_CHOOSE_ORIGINPIC);
}
});
this.relativeLayoutTakePhoto.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ReadPhotoActivity.this.takePhoto(ReadPhotoActivity.this.REQUEST_TAKE_PHOTO);
}
});
6.在拍照和讀取照片的回調(diào)當(dāng)中啟動(dòng)文本識(shí)別
private void startTextAnalyzer() {
if (this.isChosen(this.originBitmap)) {
MLFrame mlFrame = new MLFrame.Creator().setBitmap(this.originBitmap).create();
Task<MLText> task = this.textAnalyzer.asyncAnalyseFrame(mlFrame);
task.addOnSuccessListener(new OnSuccessListener<MLText>() {
@Override
public void onSuccess(MLText mlText) {
// Transacting logic for segment success.
if (mlText != null) {
ReadPhotoActivity.this.remoteDetectSuccess(mlText);
} else {
ReadPhotoActivity.this.displayFailure();
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// Transacting logic for segment failure.
ReadPhotoActivity.this.displayFailure();
return;
}
});
} else {
Toast.makeText(this.getApplicationContext(), R.string.please_select_picture, Toast.LENGTH_SHORT).show();
return;
}
}
7.識(shí)別成功后勃痴,點(diǎn)擊播放按鈕即可開(kāi)始播放
this.relativeLayoutRead.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ReadPhotoActivity.this.sourceText == null) {
Toast.makeText(ReadPhotoActivity.this.getApplicationContext(), R.string.please_select_picture, Toast.LENGTH_SHORT).show();
} else {
ReadPhotoActivity.this.mlTtsEngine.speak(sourceText, MLTtsEngine.QUEUE_APPEND);
Toast.makeText(ReadPhotoActivity.this.getApplicationContext(), R.string.read_start, Toast.LENGTH_SHORT).show();
}
}
});
Demo效果
如果你對(duì)實(shí)現(xiàn)方式感興趣谒所,可以在Github上下載源碼:https://github.com/HMS-Core/hms-ml-demo/tree/master/Homework-Reader