1. 程式人生 > >java簡單實現用語音讀txt文件

java簡單實現用語音讀txt文件

  最近比較無聊,隨便翻著部落格,無意中看到了有的人用VBS讀文字內容,也就是讀幾句中文,emmm,挺有趣的,實現也很簡單,都不需要安裝什麼環境,直接新建txt檔案,輸入一些簡單的vbs讀文字的程式碼,然後將新建的檔案字尾改為.vbs,然後雙擊一下就可以有效果了。。。。

  於是我就想啊,java行不行呢?查了一些資料,還真的行,我就將我試驗的過程說一下,就當作娛樂娛樂!

1.依賴

  隨便新建一個maven專案,匯入依賴

<dependency>
        <groupId>com.hynnet</groupId>
        <artifactId>jacob</artifactId>
        <version>1.18</version>
</dependency>

  

  只匯入依賴還不行,還要匯入一個.dll檔案,百度雲連結:連結:https://pan.baidu.com/s/1YYYPIoPxrtuyKebJzabhlw    提取碼:s62o ,可以看到有兩個dll檔案,由於我的電腦是64位的,於是我將上面那個dll檔案複製一份到當前使用jdk的bin目錄下

 

2.java程式碼實現

  一個很簡單的java程式碼實現,執行之後就會讀出來了;

package com.wyq.day66;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class Speak02 {
    
    //用電腦自帶的語音讀字串str
    public static void main(String[] args) {
         String str = "你好,我是java小新人!請叫我最帥的帥鍋";
         
         ActiveXComponent sap = new ActiveXComponent("Sapi.SpVoice");
         Dispatch sapo = sap.getObject();
         try {
             // 音量 0-100
             sap.setProperty("Volume", new Variant(100));
             // 語音朗讀速度 -10 到 +10
             sap.setProperty("Rate", new Variant(0));
             // 執行朗讀 
              Dispatch.call(sapo, "Speak", new Variant(str));
              
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             sapo.safeRelease();
             sap.safeRelease();
         }
         
    }

}

 

3.輸出音訊檔案

  按理說到上面已經實現了功能,但是我還想著能不能把讀的音訊檔案該輸出一下呢?查了查資料,居然還真行,程式碼如下:

package com.wyq.day66;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;

public class JavaSpeak {

    public static void main(String[] args) {
        //指定檔案音訊輸出檔案位置
        String output = "E:\\test.wav";
        
        ActiveXComponent ax = null;
        String str="我是java小新人,我要將這段話的音訊輸出一下";
        try {
            ax = new ActiveXComponent("Sapi.SpVoice");

            //執行時輸出語音內容
            Dispatch spVoice = ax.getObject();
            // 音量 0-100
            ax.setProperty("Volume", new Variant(100));
            // 語音朗讀速度 -10 到 +10
            ax.setProperty("Rate", new Variant(-3));
            // 進行朗讀
            Dispatch.call(spVoice, "Speak", new Variant(str));

            //下面是構建檔案流把生成語音檔案

            ax = new ActiveXComponent("Sapi.SpFileStream");
            Dispatch spFileStream = ax.getObject();

            ax = new ActiveXComponent("Sapi.SpAudioFormat");
            Dispatch spAudioFormat = ax.getObject();

            //設定音訊流格式
            Dispatch.put(spAudioFormat, "Type", new Variant(22));
            //設定檔案輸出流格式
            Dispatch.putRef(spFileStream, "Format", spAudioFormat);
            //呼叫輸出 檔案流開啟方法,在指定位置輸出一個.wav檔案
            Dispatch.call(spFileStream, "Open", new Variant(output), new Variant(3), new Variant(true));
            //設定聲音物件的音訊輸出流為輸出檔案物件
            Dispatch.putRef(spVoice, "AudioOutputStream", spFileStream);
            //設定音量 0到100
            Dispatch.put(spVoice, "Volume", new Variant(100));
            //設定朗讀速度
            Dispatch.put(spVoice, "Rate", new Variant(-2));
            //開始朗讀
            Dispatch.call(spVoice, "Speak", new Variant(str));

            //關閉輸出檔案
            Dispatch.call(spFileStream, "Close");
            Dispatch.putRef(spVoice, "AudioOutputStream", null);

            spAudioFormat.safeRelease();
            spFileStream.safeRelease();
            spVoice.safeRelease();
            ax.safeRelease();

            } catch (Exception e) {
                e.printStackTrace();
            }
    
    }

}

  直接執行我們就可以聽到朗讀的聲音,而且在指定目錄還可以找到音訊檔案;

 

4.呼叫百度AI來讀文字

  又按理說到上面應該就差不多了,但是我總是感覺電腦自帶的語音庫聲音不好聽,我要用百度AI的那個比較可愛的聲音,我還是去查了查資料,居然可以,而且很容易!

  4.1.申請一下百度語音api許可權

  由於我們是要去呼叫百度的api進行語音識別,那麼我們要先去申請一下許可權,不然會一直報錯(這個地方卡了好久,最後終於被我查出來為什麼報錯了。。。),連結:http://ai.baidu.com/

 

  然後會讓你登入一下,直接用qq登入就行;

 

   建立完畢之後檢視一下應用詳情:

 

  4.2.程式碼實現

  做了這麼多是操作就是為了得到這三個字串,現在我們還要匯入百度語音的依賴:

<!--百度語音播報sdk-->
    <dependency>
        <groupId>com.baidu.aip</groupId>
        <artifactId>java-sdk</artifactId>
        <version>4.4.1</version>
    </dependency>
    
    <!-- https://mvnrepository.com/artifact/org.json/json -->
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20160810</version>
    </dependency>

 

  桌面上記事本中的內容:

 

 

  java程式碼實現如下,其實就是利用百度AI讀取我們計算機中的一個txt文件,輸出MP3檔案儲存併到指定位置

package com.wyq.day66;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;

import org.json.JSONObject;

import com.baidu.aip.speech.AipSpeech;
import com.baidu.aip.speech.TtsResponse;
import com.baidu.aip.util.Util;

public class Speak03 {
    //設定APPID/AK/SK,這三個引數是需要我們去百度AI平臺申請的(也就是上面說的那三個字串)
    public static final String APP_ID = "16447127";
    public static final String API_KEY = "8GO31sOIffR1oll5mPFKgtR9";
    public static final String SECRET_KEY = "jWsoNGlfzfRGSQ30****NOxz9ZpjMbc";
    
    //readFile是我們的txt文件,writeFile是輸出的MP3格式
    public static String readFile = "C:\\Users\\asus\\Desktop\\says.txt";
    public static String writeFile = "E:\\output.mp3";


    public static void main(String[] args) {
        //可以直接輸入字串也行,內容比較多的話還是用txt文件比較好一點
        //convertMP3("你好!我是百度AI智慧,java小新人,很高興和你見面,我們一定能成為很好的朋友的");
        
        
        //呼叫readToString方法將一個txt文件中的資料讀取出來變成一個字串
        String string = readToString(readFile);
        //將這個字串用百度AI讀一下輸出MP3格式
        convertMP3(string);

    }
     public static void convertMP3(String str) {
            AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
            // 可選:設定網路連線引數,就是超時時間
            client.setConnectionTimeoutInMillis(2000);
            client.setSocketTimeoutInMillis(60000);

            // 設定一些可選引數
            HashMap<String, Object> options = new HashMap<String, Object>();
            options.put("spd", "5");//語速,取值0-9,預設為5中語速      非必選
            options.put("pit", "5");//音調,取值0-9,預設為5中語調      非必選
            options.put("per", "4");//發音人選擇, 0為女聲,1為男聲,3為情感合成-度逍遙,4為情感合成-度丫丫,預設為普通女 非必選
            
            //百度AI開始讀取傳入的str字串
            TtsResponse res = client.synthesis(str, "zh", 1, options);
            
            //伺服器返回的內容,合成成功時為null,失敗時包含error_no等資訊
            JSONObject result = res.getResult();   
            if (result != null) {
                System.out.printf("error:" + result.toString()+"----------");
                return;
            }
           //生成的音訊資料
            byte[] data = res.getData();            
            JSONObject res1 = res.getResult();
            if (data != null) {
                try {
                    //將生成的音訊輸出到指定位置
                    Util.writeBytesToFileSystem(data, writeFile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
            if (res1 != null) {
                System.out.println(res1.toString());
            }
        }
     
     //這個方法就是根據輸入的檔案路徑,讀取該檔案內容返回一個很長的字串,由於txt是gbk編碼,所以我們變成字串的時候也要用gbk
     //其實就是最基本的流操作
     public static String readToString(String fileName) {  
            String encoding = "gbk";  
            File file = new File(fileName);  
            Long filelength = file.length();  
            byte[] filecontent = new byte[filelength.intValue()];  
            
            try {  
                FileInputStream in = new FileInputStream(file);  
                in.read(filecontent);  
                in.close();  
            } catch (FileNotFoundException e) {  
                e.printStackTrace();  
            } catch (IOException e) {  
                e.printStackTrace();  
            }  
            
            try {  
                return new String(filecontent, encoding);  
            } catch (UnsupportedEncodingException e) {  
                System.err.println("The OS does not support " + encoding);  
                e.printStackTrace();  
                return null;  
            }  
        }
    

}

 

  輸出的音訊檔案: 

 

5.總結

   感覺還是有點兒意思的,沒事的時候用java玩一玩這些東西就當是打發時間!總是看一些框架原理啊什麼的,時間長了也是比較無聊的,可以挖掘一下java的其他功能也不