国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

科大訊飛 新版AIkit 離線語(yǔ)音聽(tīng)寫(xiě) Java 版本

這篇具有很好參考價(jià)值的文章主要介紹了科大訊飛 新版AIkit 離線語(yǔ)音聽(tīng)寫(xiě) Java 版本。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

前言:科大訊飛的新版離線語(yǔ)音聽(tīng)寫(xiě),由于官網(wǎng)demo是kt語(yǔ)言開(kāi)發(fā)的,咱也看不懂kt,搜遍了全網(wǎng)也沒(méi)看到一個(gè)java版的新版離線語(yǔ)音demo,現(xiàn)記錄下,留給有緣人參考?。。。?!畢竟咱在這上面遇到了不少的坑。如果能留言指正,那就更好了。

實(shí)測(cè)一點(diǎn)問(wèn)題都沒(méi)

一、先把官網(wǎng)Demo中resource下的文件放到sdk目錄下,示例如下

java 集成科大訊飛離線語(yǔ)言識(shí)別,訊飛語(yǔ)音識(shí)別,科大訊飛 新版離線語(yǔ)音聽(tīng)寫(xiě)java集成,訊飛 AIkit 離線語(yǔ)音聽(tīng)寫(xiě) java版本集成,語(yǔ)音識(shí)別,人工智能

一、Activity簡(jiǎn)單布局 加幾個(gè)語(yǔ)音聽(tīng)寫(xiě)的監(jiān)聽(tīng)回調(diào)

package com.mhzk.xunfeitest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;

import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;


import com.iflytek.aikit.core.AiHandle;

import com.iflytek.aikit.core.AiStatus;


public class MainActivity extends AppCompatActivity implements AbilityCallback{
    private String TAG = "內(nèi)容初始化";
    private AiStatus state;
    private AiHandle handle;
    private int REQUEST_STORAGE_PERMISSION = 100;
    private TextView start;
    private TextView content;
    private AudioRecordUtil instance;
    private StringBuffer strBuffer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        start = findViewById(R.id.one);

        content = findViewById(R.id.three);
        instance = AudioRecordUtil.getInstance();
        instance.initSDK(this);
        AudioRecordUtil.setCallBack(this);
        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(start.getText().toString().equals("開(kāi)始錄音")){
                    instance.start(MainActivity.this);
                }else {
                    instance.stop();
                }

            }
        });

        
        requestStoragePermission(this);

    }






    /**
     * 查看當(dāng)前設(shè)備是否有存儲(chǔ)權(quán)限:
     *      沒(méi)有:請(qǐng)求獲取權(quán)限
     *      有:復(fù)制當(dāng)前項(xiàng)目assets下的xtts文件夾到設(shè)備根目錄下(語(yǔ)音合成所必須的文件)
     * @param context
     */
    private void requestStoragePermission(Context context) {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    REQUEST_STORAGE_PERMISSION);
        }
    }

    /**
     * 請(qǐng)求獲取存儲(chǔ)權(quán)限
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_STORAGE_PERMISSION) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Log.i(TAG, "onRequestPermissionsResult: permission granted");
                //再次判斷存儲(chǔ)權(quán)限是否已授予
                boolean permission = FileUtils.hasStoragePermission(getApplicationContext());
                if (!permission) {
                    Toast.makeText(getApplicationContext(), "沒(méi)有存儲(chǔ)權(quán)限,請(qǐng)重新獲取!", Toast.LENGTH_SHORT).show();
                    return;
                }
                // 應(yīng)用具有存儲(chǔ)權(quán)限
                Log.i(TAG,"成功獲取存儲(chǔ)權(quán)限!");
                //判斷xtts文件是否存在,不存在則復(fù)制,存在則忽略
                FileUtils.createXttsDirAndCopyFile(getApplicationContext());
            } else {
                Log.i(TAG, "onRequestPermissionsResult: permission denied");
                Toast.makeText(this, "You Denied Permission", Toast.LENGTH_SHORT).show();
            }
        }
    }


    /**
     * 開(kāi)始
     */
    @Override
    public void onAbilityBegin() {
        start.setText("暫停錄音");
        content.setText("內(nèi)容展示");
    }

    /**
     *能力結(jié)果輸出
     * @param result 結(jié)果
     */
    @Override
    public void onAbilityResult(String result) {
        String s = content.getText().toString();
        strBuffer = new StringBuffer(s);
        strBuffer.append("\n"+result );
        String value = strBuffer.toString();

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                content.setText(value);
            }
        });
    }

    /**
     *結(jié)束
     * @param code
     * @param error
     */
    @Override
    public void onAbilityError(int code, Throwable error) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                start.setText("開(kāi)始錄音");
            }
        });

        instance.stop();
    }

    /**
     * 能力結(jié)束
     */
    @Override
    public void onAbilityEnd() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                start.setText("開(kāi)始錄音");
            }
        });
    }
}

二、AudioRecord進(jìn)行音頻錄制并寫(xiě)入本地創(chuàng)建的pcm文件

????????寫(xiě)入過(guò)程中把流數(shù)據(jù)復(fù)制一份傳給sdk做文字轉(zhuǎn)換

package com.mhzk.xunfeitest;

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioFormat;

import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Environment;
import android.util.Log;

import androidx.annotation.NonNull;

import com.iflytek.aikit.core.AiAudio;
import com.iflytek.aikit.core.AiEvent;
import com.iflytek.aikit.core.AiHandle;
import com.iflytek.aikit.core.AiHelper;
import com.iflytek.aikit.core.AiListener;
import com.iflytek.aikit.core.AiRequest;
import com.iflytek.aikit.core.AiResponse;
import com.iflytek.aikit.core.AiStatus;
import com.iflytek.aikit.core.AuthListener;
import com.iflytek.aikit.core.DataStatus;
import com.iflytek.aikit.core.ErrType;



import java.io.File;

import java.io.FileOutputStream;

import java.io.OutputStream;
import java.io.UnsupportedEncodingException;

import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

public class AudioRecordUtil {
    private static final String TAG = "AudioPlayByKeyUtils";
    //設(shè)置音頻采樣率,44100是目前的標(biāo)準(zhǔn),但是某些設(shè)備仍然支持22050,16000,11025
    private final int sampleRateInHz = 16000;
    //設(shè)置音頻的錄制的聲道CHANNEL_IN_STEREO為雙聲道,CHANNEL_CONFIGURATION_MONO為單聲道
    private final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
    //音頻數(shù)據(jù)格式:PCM 16位每個(gè)樣本。保證設(shè)備支持。PCM 8位每個(gè)樣本。不一定能得到設(shè)備支持。
    private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    //錄制狀態(tài)
    private boolean recorderState = true;
    private byte[] buffer;
    private static AudioRecord audioRecord;
    private static AudioRecordUtil audioRecordUtil = new AudioRecordUtil();

    private static AiHandle handle;
    private File recordFile;
    private AtomicBoolean atomicBoolean = new AtomicBoolean();
    private byte[] lockArray = new byte[0];
    private int recordMinBufferSize;


    //SDK初始化
    public   void initSDK(Context context) {
        try {
            //外部存儲(chǔ)絕對(duì)路徑
            File externalStorageDirectory = Environment.getExternalStorageDirectory();
            // 初始化參數(shù)構(gòu)建
            AiHelper.Params params = AiHelper.Params.builder()
                    .appId(context.getString(R.string.appId))
                    .apiKey(context.getString(R.string.apiKey))
                    .apiSecret(context.getString(R.string.apiSecret))
                    .workDir("/sdcard/iflytekAikit")//SDK工作路徑,這里為絕對(duì)路徑
                    .authInterval(333) //授權(quán)更新間隔
                    .build();
            // 初始化
            AiHelper.getInst().init(context, params);
            // 注冊(cè)SDK 初始化狀態(tài)監(jiān)聽(tīng)
            AiHelper.getInst().registerListener(coreListener);
            // 注冊(cè)能力結(jié)果監(jiān)聽(tīng)  R.string.enginID 為離線的語(yǔ)音聽(tīng)寫(xiě)ID,寫(xiě)死就好 ee62fa27c
            AiHelper.getInst().registerListener(context.getString(R.string.enginID), aiRespListener);
        } catch (Exception e) {
            Log.e(TAG, "語(yǔ)音合成初始化出現(xiàn)異常" + e.getMessage());
        }
    }


    public static AudioRecordUtil getInstance() {
        return audioRecordUtil;
    }

    private AudioRecordUtil() {
        init();
    }

    @SuppressLint("MissingPermission")
    private void init() {
        recordMinBufferSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
        //指定 AudioRecord 緩沖區(qū)大小
        buffer = new byte[recordMinBufferSize];
        //根據(jù)錄音參數(shù)構(gòu)造AudioRecord實(shí)體對(duì)象
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig,
                audioFormat, recordMinBufferSize);
    }

    /**
     * 開(kāi)始錄制
     */
    public void start(Context context) {
        //已初始化則略過(guò)
//        initSDK(context);

        //能力逆初始化, 部分能力,比如語(yǔ)種切換的時(shí)候 需要逆初始化
        AiHelper.getInst().engineUnInit(context.getString(R.string.enginID));
        int ret = -1;
        ret = AiHelper.getInst().engineInit(context.getString(R.string.enginID));
        if (ret != 0) {
                abilityCallback.onAbilityError(ret, new Throwable("引擎初始化失?。?ret"));
            return;
        }
        int[] indexs0 = {0};
        int[] indexs1 = {1};
        ret = AiHelper.getInst()
                        .specifyDataSet(context.getString(R.string.enginID), "PPROC_NOT_REP", indexs0);
        if (ret != 0) {
            abilityCallback.onAbilityError(ret, new Throwable("open esr specifyDataSet 失敗:$ret"));

            return;
        }
        ret = AiHelper.getInst()
                .specifyDataSet(context.getString(R.string.enginID), "PPROC_REPLACE",indexs1);
        if (ret != 0) {
            abilityCallback.onAbilityError(ret, new Throwable("open esr specifyDataSet 失?。?ret"));

            return;
        }

        //音量及播報(bào)人等參數(shù)設(shè)置
        AiRequest.Builder paramBuilder = audioParam();
        handle = AiHelper.getInst().start(context.getString(R.string.enginID), paramBuilder.build(), null);
        atomicBoolean.set(true);
        if (!handle.isSuccess()) {
            Log.e(TAG, "ERROR::START | handle code:" + handle.getCode());
            return;
        }
        if (audioRecord.getState() == AudioRecord.RECORDSTATE_STOPPED) {
            recorderState = true;
            audioRecord.startRecording();
            abilityCallback.onAbilityBegin();
            String absolutePath = MyApp.mApplication.getExternalCacheDir().getAbsolutePath();
            recordFile = new File(absolutePath + "/" + System.currentTimeMillis() + ".pcm");
        }else {
            init();
            recorderState = true;
            audioRecord.startRecording();
            abilityCallback.onAbilityBegin();
            String absolutePath = MyApp.mApplication.getExternalCacheDir().getAbsolutePath();
            recordFile = new File(absolutePath + "/" + System.currentTimeMillis() + ".pcm");
        }
        new RecordThread().start();
    }




    /**
     * 停止錄制
     */
    public void stop() {
        recorderState = false;
        if (audioRecord.getState() == AudioRecord.RECORDSTATE_RECORDING) {
            audioRecord.stop();
        }
        audioRecord.release();
        int ret = AiHelper.getInst().end(handle);
        if (ret != 0) {
            String error = "end failed" + ret;
            Log.e(TAG, error);
        }
    }


    private class RecordThread extends Thread {

        @Override
        public void run() {
            //輸出流
            OutputStream os = null;
            try {
                os = new FileOutputStream(recordFile);
//                BufferedOutputStream bos = new BufferedOutputStream(os);
//                DataOutputStream dos = new DataOutputStream(bos);
                while (recorderState) {
                    int read = audioRecord.read(buffer, 0, buffer.length);
                    for (int i = 0; i < read; i++) {
//                        dos.writeShort(buffer[i]);
                    }
                    if (read == recordMinBufferSize) {
                        AiStatus status = AiStatus.CONTINUE;
                        if (atomicBoolean.get()) {
                            status = AiStatus.BEGIN;
                            atomicBoolean.set(false);
                        }
                        writeData(buffer, status);
                    } else {
                        byte[] copy = new byte[read];
                        System.arraycopy(buffer, 0, copy, 0, read);

                        AiStatus status = AiStatus.CONTINUE;
                        if (atomicBoolean.get()) {
                            status = AiStatus.BEGIN;
                            atomicBoolean.set(false);
                        }
                        writeData(copy, status);
                    }
                    os.write(buffer);

                }
                os.flush();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 寫(xiě)入音頻數(shù)據(jù)
     *
     * @param status 送入的數(shù)據(jù)的狀態(tài),告訴引擎送入的首幀數(shù)據(jù)、中間數(shù)據(jù)、還是尾幀
     */
    private void writeData(byte[] audio, AiStatus status) {
        if (handle == null) {
            return;
        }
        synchronized (lockArray) {
            AiRequest.Builder dataBuilder = AiRequest.builder();
            AiAudio.Holder holder = AiAudio.get("PCM").data(audio);
            holder.status(status);
            dataBuilder.payload(holder.valid());
            int ret = AiHelper.getInst().write(dataBuilder.build(), handle);
            if (ret != 0) {
                destory();
                Log.w(TAG, "writeData is error => $ret");
            } else {
                ret = AiHelper.getInst().read("ee62fa27c", handle);
                if (ret != 0) {
                    Log.w(TAG, "read error code => $ret");
                    destory();
                } else {
                    Log.w(TAG, "read success code => $ret");
                }
            }
        }
    }


    /**
     * SDK監(jiān)聽(tīng)回調(diào)
     */
    private static AuthListener coreListener = new AuthListener() {
        @Override
        public void onAuthStateChange(final ErrType type, final int code) {
            Log.i(TAG, "core listener code:" + code);
            switch (type) {
                case AUTH:
                    Log.i(TAG, "SDK狀態(tài):授權(quán)結(jié)果碼" + code);
                    break;
                case HTTP:
                    Log.i(TAG, "SDK狀態(tài):HTTP認(rèn)證結(jié)果" + code);
                    break;
                default:
                    Log.i(TAG, "SDK狀態(tài):其他錯(cuò)誤");
            }
        }
    };


    /**
     * 能力監(jiān)聽(tīng)回調(diào)
     */
    private static AiListener aiRespListener = new AiListener() {
        //獲取合成結(jié)果,封裝到緩存數(shù)組中
        @Override
        public void onResult(int handleID, List<AiResponse> outputData, Object usrContext) {
            if (outputData == null || outputData.isEmpty()) {
                return;
            }
            if (null != outputData && outputData.size() > 0) {
                for (int i = 0; i < outputData.size(); i++) {
                    byte[] bytes = outputData.get(i).getValue();
                    String key = outputData.get(i).getKey();

                    if (key.contains("plain") || key.contains("pgs")) {
                        try {
                            String s = new String(bytes, "GBK");
                            Log.e(TAG, key + "      " + s);
                            abilityCallback.onAbilityResult(key+ "  "+s);
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                        if (key.contains("plain")) {
                            stopAsr();
                        }
                    }
                }
                if (outputData.get(0).getStatus() == DataStatus.END.getValue()) {
                    stopAsr();
                }
            }
        }

        @Override
        public void onEvent(int handleID, int event, List<AiResponse> eventData, Object usrContext) {
            if (event == AiEvent.EVENT_UNKNOWN.getValue()) {
            }
            if (event == AiEvent.EVENT_START.getValue()) {
            }
            if (event == AiEvent.EVENT_END.getValue()) {
                if (handle != null) {
                    int rets = AiHelper.getInst().end(handle);
                    if (rets != 0) {
                        String error = "end failed" + rets;
                        Log.e(TAG, error);
                    }
                }

            }
            if (event == AiEvent.EVENT_PROGRESS.getValue()) {

            }
        }

        @Override
        public void onError(int handleID, int err, String msg, Object usrContext) {
            if (handle != null) {
                int rets = AiHelper.getInst().end(handle);
                if (rets != 0) {
                    String error = "end failed" + rets;
                    Log.e(TAG, error);
                }
            }
        }
    };


    /**
     * 音量及播報(bào)人等參數(shù)設(shè)置
     */
    @NonNull
    private static AiRequest.Builder audioParam() {
        AiRequest.Builder paramBuilder = AiRequest.builder();
        paramBuilder.param("lmLoad", true);
        paramBuilder.param("vadLoad", true);
        paramBuilder.param("puncLoad", true);
        paramBuilder.param("numLoad", true);
        paramBuilder.param("postprocOn", true);
        paramBuilder.param("lmOn", true);
        paramBuilder.param("vadOn", true);
        paramBuilder.param("vadLinkOn", false);
        paramBuilder.param("vadNeed", true);
        paramBuilder.param("vadThreshold", 0.1332);
        paramBuilder.param("vadEnergyThreshold", 9);
        return paramBuilder;
    }

    /**
     * 釋放資源
     */
    public static void destory() {
        stopAsr();
    }

    /**
     * 停止語(yǔ)音識(shí)別
     */
    private static void stopAsr() {
        if (audioRecord != null) {
            if (audioRecord.getState() == AudioRecord.STATE_INITIALIZED) {
                audioRecord.stop();
            }
        }
        audioRecord.release();
        int ret = AiHelper.getInst().end(handle);
        if (ret == 0) {
            abilityCallback.onAbilityEnd();
        } else {
            abilityCallback.onAbilityError(ret, new Throwable("aiHandle end error"));
        }
    }




    private static AbilityCallback abilityCallback;

    public static void setCallBack(AbilityCallback callBack) {
        abilityCallback = callBack;
    }




}

接口類(lèi)

package com.mhzk.xunfeitest;

public interface AbilityCallback {

        /**
         * 開(kāi)始
         */
        void onAbilityBegin();

        /**
         * 能力結(jié)果輸出
         *
         * @param result 結(jié)果
         */
        void onAbilityResult(String result);

        /**
         * 結(jié)束
         *
         * @param code
         * @param error
         */
        void onAbilityError(int code, Throwable error);

        /**
         * 能力結(jié)束
         */
        void onAbilityEnd();

}

Activity中權(quán)限使用類(lèi),用不用都行,看自己

package com.mhzk.xunfeitest;


import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.os.Build;
import android.os.Environment;
import android.util.Log;



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * 訊飛語(yǔ)音合成文件復(fù)制公共功能
 *	以下五個(gè)文件:
 *		e3fe94474_1.0.0_xTTS_CnCn_xiaoyan_2018_arm.irf
 *		e4b08c6f3_1.0.0_xTTS_CnCn_xiaofeng_2018_fix_arm.dat
 *		e4caee636_1.0.2_xTTS_CnCn_front_Emb_arm_2017.irf
 *		e05d571cc_1.0.0_xTTS_CnCn_xiaoyan_2018_fix_arm.dat
 *		ebdbd61ae_1.0.0_xTTS_CnCn_xiaofeng_2018_arm.irf
 */
public class FileUtils {
    private static final String TAG = "FileUtils";
    // 獲取外部存儲(chǔ)路徑
    public static String getExternalStoragePath() {
        return Environment.getExternalStorageDirectory().getAbsolutePath();
    }

    // 創(chuàng)建xtts目錄
    public static void createDirectory(String directoryPath) {
        File directory = new File(directoryPath);
        if (!directory.exists()) {
            if (directory.mkdirs()) {
                Log.d(TAG, "Directory created: " + directoryPath);
            } else {
                Log.e(TAG, "Failed to create directory: " + directoryPath);
            }
        } else {
            Log.d(TAG, "Directory already exists: " + directoryPath);
        }
    }

    // 判斷目錄是否為空
    public static boolean isDirectoryEmpty(String directoryPath) {
        File directory = new File(directoryPath);
        if (directory.exists() && directory.isDirectory()) {
            File[] files = directory.listFiles();
            return files == null || files.length == 0;
        }
        return true;
    }

    // 遞歸復(fù)制文件
    public static void copyFiles(Context context, String sourceDir, String destinationDir) throws IOException {
        AssetManager assetManager = context.getAssets();
        String[] files = assetManager.list(sourceDir);
        if (files != null && files.length > 0) {
            createDirectory(destinationDir);
            for (String fileName : files) {
                String sourcePath = sourceDir + File.separator + fileName;
                String destinationPath = destinationDir + File.separator + fileName;

                if (assetManager.list(sourcePath).length > 0) {
                    // 如果是目錄,遞歸復(fù)制目錄
                    copyFiles(context, sourcePath, destinationPath);
                } else {
                    // 如果是文件,復(fù)制文件
                    copyFile(context, sourcePath, destinationPath);
                }
            }
        }
    }

    // 復(fù)制文件
    public static void copyFile(Context context, String sourcePath, String destinationPath) throws IOException {
        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            inputStream = context.getAssets().open(sourcePath);
            outputStream = new FileOutputStream(destinationPath);
            byte[] buffer = new byte[4096];
            int length;
            while ((length = inputStream.read(buffer)) > 0) {
                outputStream.write(buffer, 0, length);
            }
            Log.d(TAG, "File copied: " + destinationPath);
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    Log.e(TAG, "Failed to close input stream", e);
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    Log.e(TAG, "Failed to close output stream", e);
                }
            }
        }
    }

    /**
     * 創(chuàng)建訊飛語(yǔ)音合成所必須的目錄:xtts并復(fù)制音頻文件
     * @param context
     */
    public static void createXttsDirAndCopyFile(Context context){
        // 獲取外部存儲(chǔ)路徑
        String externalStoragePath = FileUtils.getExternalStoragePath();

        String xttsFolderPath = externalStoragePath + File.separator + context.getString(R.string.dir);
        // 創(chuàng)建xtts文件夾
        FileUtils.createDirectory(xttsFolderPath);
        // 判斷xtts文件夾是否為空
        if (FileUtils.isDirectoryEmpty(xttsFolderPath)) {
            // 復(fù)制assets目錄下的xtts文件夾中的所有文件到外部存儲(chǔ)的xtts文件夾中
            try {
                FileUtils.copyFiles(context, context.getString(R.string.dir), xttsFolderPath);
            } catch (IOException e) {
                Log.e(TAG, "文件復(fù)制失敗"+e.getMessage());
            }
        } else {
            // xtts文件夾不為空
            Log.d(TAG, "xtts folder is not empty. Skipping the operation.");
        }
    }

    public static boolean hasStoragePermission(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            int permissionResult = context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
            return permissionResult == PackageManager.PERMISSION_GRANTED;
        }
        return true;
    }

}

Activity的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="開(kāi)始錄音"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />




    <TextView
        android:layout_marginTop="20dp"
        android:id="@+id/three"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="內(nèi)容展示"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</LinearLayout>

?要demo的可以私信

?文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-835530.html

到了這里,關(guān)于科大訊飛 新版AIkit 離線語(yǔ)音聽(tīng)寫(xiě) Java 版本的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C#調(diào)用科大訊飛離線語(yǔ)音合成實(shí)現(xiàn)文本轉(zhuǎn)語(yǔ)音

    C#調(diào)用科大訊飛離線語(yǔ)音合成實(shí)現(xiàn)文本轉(zhuǎn)語(yǔ)音

    文本轉(zhuǎn)語(yǔ)音(Text To Speech),簡(jiǎn)稱(chēng)TTS,在很多業(yè)務(wù)場(chǎng)景會(huì)用到,比如廣播大廳,人機(jī)互動(dòng)等。C#要實(shí)現(xiàn)TTS有不少選擇,比如調(diào)用System.Speech,此處就不細(xì)說(shuō)了,下面主要介紹一下C#調(diào)用科大訊飛的離線語(yǔ)音合成SDK來(lái)實(shí)現(xiàn)文本轉(zhuǎn)語(yǔ)音。 地址:[https://www.xfyun.cn/service/offline_tts] 一、創(chuàng)建

    2024年02月12日
    瀏覽(18)
  • 科大訊飛語(yǔ)音合成Java springboot集成

    科大訊飛語(yǔ)音合成 文本轉(zhuǎn)語(yǔ)音 一、引入依賴(lài): 二、下載響應(yīng)的sdk,我這里是下載的java win版本的sdk SDK下載 - 科大訊飛api接口 - 訊飛開(kāi)放平臺(tái) 三、具體代碼: 從下載的依賴(lài)?yán)锩嬲业綄?duì)應(yīng)文件,給代碼里面替換成你的絕對(duì)路徑,運(yùn)行即可 備注:這個(gè)地方需要你自己的賬號(hào)下載

    2024年02月15日
    瀏覽(18)
  • Unity2021接入訊飛語(yǔ)音聽(tīng)寫(xiě)(Android)

    Unity2021接入訊飛語(yǔ)音聽(tīng)寫(xiě)(Android)

    使用的引擎工具: Unity2021.3.19 android-studio-2021.1.21 第一步: 新建一個(gè)Android項(xiàng)目(工程名字隨便啦) 然后新建一個(gè)library (同上,庫(kù)名自己命名吧) Android環(huán)境目前就算是初步建立好了。 第二步: 導(dǎo)包 libs文件夾里面放入這4個(gè)文件,arm64-v8a,armeabi-v7a,Msc.jar這三個(gè)文件是訊飛官

    2024年02月06日
    瀏覽(15)
  • GEC6818開(kāi)發(fā)板JPG圖像顯示,科大訊飛離線語(yǔ)音識(shí)別包Linux_aitalk_exp1227_1398d7c6運(yùn)行demo程序,開(kāi)發(fā)板實(shí)現(xiàn)錄音

    GEC6818開(kāi)發(fā)板JPG圖像顯示,科大訊飛離線語(yǔ)音識(shí)別包Linux_aitalk_exp1227_1398d7c6運(yùn)行demo程序,開(kāi)發(fā)板實(shí)現(xiàn)錄音

    體積小,使用到數(shù)據(jù)結(jié)構(gòu)里面的 霍夫曼樹(shù)(哈夫曼樹(shù)) 對(duì)數(shù)據(jù)進(jìn)行壓縮 1.對(duì)jpegsrc.v8c.tar.gz進(jìn)行arm移植 移植方式如下: 1.將jpegsrc.v8c.tar.gz解壓縮到ubuntu ~ 2.進(jìn)入~/jpeg-8c對(duì)jpeg庫(kù)進(jìn)行配置 3.編譯 4.安裝,將動(dòng)態(tài)庫(kù)存放到 /home/gec/armJPegLib 5.清空編譯記錄 6.自己查看下 /home/gec/armJPegLib目

    2024年01月17日
    瀏覽(25)
  • Java中實(shí)現(xiàn)在線語(yǔ)音識(shí)別(科大訊飛免費(fèi)的SKD)、SDK下載和IDEA項(xiàng)目搭建、成功運(yùn)行【完整代碼】

    Java中實(shí)現(xiàn)在線語(yǔ)音識(shí)別(科大訊飛免費(fèi)的SKD)、SDK下載和IDEA項(xiàng)目搭建、成功運(yùn)行【完整代碼】

    科大訊飛官網(wǎng):https://www.xfyun.cn/ 首先登陸訊飛開(kāi)放平臺(tái):https://passport.xfyun.cn/login,微信掃碼關(guān)注登錄 注冊(cè)新賬號(hào) 登陸后界面后,進(jìn)入產(chǎn)品服務(wù)–實(shí)時(shí)語(yǔ)音轉(zhuǎn)寫(xiě)欄目 點(diǎn)擊個(gè)人免費(fèi)套餐,下面的立即領(lǐng)取,它會(huì)提醒我們?nèi)?shí)名認(rèn)證 實(shí)名認(rèn)證一下 提交完認(rèn)證之后 可以看到認(rèn)證

    2023年04月21日
    瀏覽(46)
  • 科大訊飛語(yǔ)音SDK下載及測(cè)試

    科大訊飛語(yǔ)音SDK下載及測(cè)試

    一、SDK 下載 進(jìn)入訊飛開(kāi)發(fā)平臺(tái)官網(wǎng)http://www.xfyun.cn/,右上角進(jìn)行注冊(cè)登錄,登錄后點(diǎn)擊進(jìn)入SDK下載。 ?? ????????2.創(chuàng)建新應(yīng)用 ????? ????????3.填入相關(guān)信息 ????????4.創(chuàng)建完后提交后回到SDK下載頁(yè)面,刷新頁(yè)面,應(yīng)用選擇前面創(chuàng)建的應(yīng)用,平臺(tái)選擇Linux,SDK選擇

    2024年02月08日
    瀏覽(43)
  • vue 利用科大訊飛實(shí)現(xiàn)實(shí)時(shí)語(yǔ)音轉(zhuǎn)寫(xiě)

    1:新建js文件,該文件在科大訊飛api的demo種可以找到 2: 引入第一個(gè)文件在vue頁(yè)面中 3:如果在引入的過(guò)程中有些關(guān)于worker的報(bào)錯(cuò),可以參考以下方法? 在vue.config.js中加入 ?

    2024年02月12日
    瀏覽(21)
  • 技術(shù)解讀 | 科大訊飛語(yǔ)音技術(shù)最新進(jìn)展之二:語(yǔ)音識(shí)別與語(yǔ)音合成

    技術(shù)解讀 | 科大訊飛語(yǔ)音技術(shù)最新進(jìn)展之二:語(yǔ)音識(shí)別與語(yǔ)音合成

    這一篇內(nèi)容將圍繞語(yǔ)音識(shí)別與合成方向,繼續(xù)為大家?guī)?lái)相關(guān)技術(shù)解析。 “風(fēng)物長(zhǎng)宜放眼量”。面向人機(jī)交互更加自然流暢的未來(lái),智能語(yǔ)音技術(shù)進(jìn)展如何?該走向何方? 以下內(nèi)容根據(jù)訊飛研究院杰出科學(xué)家潘嘉在NCMMSC 2022上的主題演講《科大訊飛語(yǔ)音技術(shù)前沿進(jìn)展》整理。

    2024年02月07日
    瀏覽(74)
  • 微信小程序調(diào)用科大訊飛 在線合成語(yǔ)音接口(文字轉(zhuǎn)語(yǔ)音)

    科大訊飛在線文檔 https://www.xfyun.cn/doc/tts/online_tts/API.html 科大訊飛調(diào)用接口 地址 https://blog.csdn.net/jinxi1112/article/details/122835386 微信小程序base64轉(zhuǎn)ArrayBuffer替代方案 https://www.homedt.net/43939.html 注意點(diǎn) 調(diào)用函數(shù) 參考大佬的實(shí)例 這里說(shuō)一下注意的點(diǎn) 微信小程序 不支持在線的 base64

    2024年02月10日
    瀏覽(29)
  • UE4如何接入科大訊飛的語(yǔ)音識(shí)別

    UE4如何接入科大訊飛的語(yǔ)音識(shí)別

    本文用的是UE4 4.27測(cè)試 安卓版測(cè)試鏈接: 鏈接:https://pan.baidu.com/s/1CsdJecfyMTdxNd6XfSECQQ 提取碼:m122 B站視頻連接:https://space.bilibili.com/449549424?spm_id_from=333.1007.0.0 GitHub地址:https://github.com/zhangmei126/XunFei 第一步 新建一個(gè)VS的UE4 4.27項(xiàng)目工程(注意是UE4 4.27 VS項(xiàng)目) 第二步 新建一

    2023年04月08日
    瀏覽(51)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包