forked from go/golangs_learn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
416 lines
10 KiB
416 lines
10 KiB
package aliyun
|
|
|
|
import (
|
|
"github.com/buger/jsonparser"
|
|
"regexp"
|
|
"strings"
|
|
"unicode"
|
|
"unicode/utf8"
|
|
"videosrt/app/tool"
|
|
)
|
|
|
|
|
|
type AliyunAudioRecognitionResultBlock struct {
|
|
AliyunAudioRecognitionResult
|
|
Blocks []int
|
|
BlockEmptyTag bool
|
|
BlockEmptyHandle bool
|
|
}
|
|
|
|
//阿里云录音录音文件识别 - 智能分段处理
|
|
func AliyunAudioResultWordHandle(result [] byte , callback func (vresult *AliyunAudioRecognitionResult)) {
|
|
var audioResult = make(map[int64][] *AliyunAudioRecognitionResultBlock)
|
|
var wordResult = make(map[int64][]*AliyunAudioWord)
|
|
var err error
|
|
|
|
//获取录音识别数据集
|
|
_, err = jsonparser.ArrayEach(result, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
|
|
text , _ := jsonparser.GetString(value, "Text")
|
|
channelId , _ := jsonparser.GetInt(value, "ChannelId")
|
|
beginTime , _ := jsonparser.GetInt(value, "BeginTime")
|
|
endTime , _ := jsonparser.GetInt(value, "EndTime")
|
|
silenceDuration , _ := jsonparser.GetInt(value, "SilenceDuration")
|
|
speechRate , _ := jsonparser.GetInt(value, "SpeechRate")
|
|
emotionValue , _ := jsonparser.GetInt(value, "EmotionValue")
|
|
|
|
vresult := &AliyunAudioRecognitionResultBlock {}
|
|
vresult.Text = text
|
|
vresult.ChannelId = channelId
|
|
vresult.BeginTime = beginTime
|
|
vresult.EndTime = endTime
|
|
vresult.SilenceDuration = silenceDuration
|
|
vresult.SpeechRate = speechRate
|
|
vresult.EmotionValue = emotionValue
|
|
|
|
_ , isPresent := audioResult[channelId]
|
|
if isPresent {
|
|
//追加
|
|
audioResult[channelId] = append(audioResult[channelId] , vresult)
|
|
} else {
|
|
//初始
|
|
audioResult[channelId] = []*AliyunAudioRecognitionResultBlock{}
|
|
audioResult[channelId] = append(audioResult[channelId] , vresult)
|
|
}
|
|
} , "Result", "Sentences")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
//获取词语数据集
|
|
_, err = jsonparser.ArrayEach(result , func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
|
|
word , _ := jsonparser.GetString(value, "Word")
|
|
channelId , _ := jsonparser.GetInt(value, "ChannelId")
|
|
beginTime , _ := jsonparser.GetInt(value, "BeginTime")
|
|
endTime , _ := jsonparser.GetInt(value, "EndTime")
|
|
vresult := &AliyunAudioWord{
|
|
Word:word,
|
|
ChannelId:channelId,
|
|
BeginTime:beginTime,
|
|
EndTime:endTime,
|
|
}
|
|
_, isPresent := wordResult[channelId]
|
|
if isPresent {
|
|
//追加
|
|
wordResult[channelId] = append(wordResult[channelId] , vresult)
|
|
} else {
|
|
//初始
|
|
wordResult[channelId] = []*AliyunAudioWord{}
|
|
wordResult[channelId] = append(wordResult[channelId] , vresult)
|
|
}
|
|
} , "Result" , "Words")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
|
|
var symbol = []string{"?","。",",","!",";","、","?",".",",","!"}
|
|
//数据集处理
|
|
for _ , value := range audioResult {
|
|
for _ , data := range value {
|
|
// filter
|
|
data.Text = FilterText(data.Text)
|
|
|
|
data.Blocks = GetTextBlock(data.Text)
|
|
data.Text = ReplaceStrs(data.Text , symbol , "")
|
|
|
|
if len(data.Blocks) == 0 {
|
|
data.BlockEmptyTag = true
|
|
}
|
|
}
|
|
}
|
|
|
|
//遍历输出
|
|
for _,value := range wordResult {
|
|
|
|
var block string = ""
|
|
var blockRune int = 0
|
|
var lastBlock int = 0
|
|
|
|
var beginTime int64 = 0
|
|
var blockBool = false
|
|
|
|
var ischinese = IsChineseWords(value) //校验中文
|
|
|
|
var chineseNumberWordIndexs []int
|
|
var chineseNumberDiffLength int = 0
|
|
|
|
for i , word := range value {
|
|
if blockBool || i == 0 {
|
|
beginTime = word.BeginTime
|
|
blockBool = false
|
|
}
|
|
|
|
if ischinese && block == "" {
|
|
chineseNumberWordIndexs = []int{}
|
|
chineseNumberDiffLength = 0
|
|
}
|
|
|
|
if ischinese {
|
|
block += word.Word
|
|
if tool.CheckChineseNumber(word.Word) && FindSliceIntCount(chineseNumberWordIndexs , i) == 0 {
|
|
cl := tool.ChineseNumberToLowercaseLength(word.Word) - utf8.RuneCountInString(word.Word)
|
|
if cl > 0 {
|
|
chineseNumberDiffLength += cl
|
|
chineseNumberWordIndexs = append(chineseNumberWordIndexs , i)
|
|
} else {
|
|
//例外
|
|
if i != 0 {
|
|
newWord := value[i-1].Word + word.Word
|
|
cl := tool.ChineseNumberToLowercaseLength(newWord) - utf8.RuneCountInString(newWord)
|
|
if cl > 0 {
|
|
chineseNumberDiffLength += cl
|
|
chineseNumberWordIndexs = append(chineseNumberWordIndexs , i)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
block += CompleSpace(word.Word) //补全空格
|
|
}
|
|
|
|
blockRune = utf8.RuneCountInString(block)
|
|
|
|
//fmt.Println("chineseNumberDiffLength : " , chineseNumberWordIndexs , chineseNumberDiffLength , word.Word)
|
|
|
|
for channel , p := range audioResult {
|
|
if word.ChannelId != channel {
|
|
continue
|
|
}
|
|
|
|
for windex , w := range p {
|
|
|
|
if (word.BeginTime >= w.BeginTime && word.EndTime <= w.EndTime) || ((word.BeginTime < w.EndTime && word.EndTime > w.EndTime) && (FindSliceIntCount(w.Blocks , -1) != len(w.Blocks))) {
|
|
flag := false
|
|
early := false
|
|
|
|
if !w.BlockEmptyTag {
|
|
for t , B := range w.Blocks{
|
|
//fmt.Println("blockRune : " , blockRune , B , word.Word)
|
|
if ((blockRune >= B) || (blockRune + chineseNumberDiffLength >= B)) && B != -1 {
|
|
flag = true
|
|
|
|
//fmt.Println(w.Blocks)
|
|
//fmt.Println(B , lastBlock , (B - lastBlock) , word.Word)
|
|
//fmt.Println(w.Text)
|
|
//fmt.Println( block )
|
|
//fmt.Println("\n")
|
|
|
|
var thisText = ""
|
|
//容错机制
|
|
if t == (len(w.Blocks) - 1) {
|
|
thisText = SubString(w.Text , lastBlock , 10000)
|
|
} else {
|
|
//下个词提前结束
|
|
if i < len(value)-1 && value[i+1].BeginTime >= w.EndTime{
|
|
thisText = SubString(w.Text , lastBlock , 10000)
|
|
early = true
|
|
} else {
|
|
thisText = SubString(w.Text , lastBlock , (B - lastBlock))
|
|
}
|
|
}
|
|
|
|
lastBlock = B
|
|
if early == true {
|
|
//全部设置为-1
|
|
for vt,vb := range w.Blocks{
|
|
if vb != -1 {
|
|
w.Blocks[vt] = -1;
|
|
}
|
|
}
|
|
} else {
|
|
w.Blocks[t] = -1
|
|
}
|
|
|
|
vresult := &AliyunAudioRecognitionResult{
|
|
Text:thisText,
|
|
ChannelId:channel,
|
|
BeginTime:beginTime,
|
|
EndTime:word.EndTime,
|
|
SilenceDuration:w.SilenceDuration,
|
|
SpeechRate:w.SpeechRate,
|
|
EmotionValue:w.EmotionValue,
|
|
}
|
|
callback(vresult) //回调传参
|
|
|
|
blockBool = true
|
|
break
|
|
}
|
|
}
|
|
|
|
//fmt.Println("word.Word : " , word.Word)
|
|
//fmt.Println(block)
|
|
|
|
if FindSliceIntCount(w.Blocks , -1) == len(w.Blocks) {
|
|
//全部截取完成
|
|
block = ""
|
|
lastBlock = 0
|
|
}
|
|
//容错机制
|
|
if FindSliceIntCount(w.Blocks , -1) == (len(w.Blocks)-1) && flag == false {
|
|
var thisText = SubString(w.Text , lastBlock , 10000)
|
|
|
|
w.Blocks[len(w.Blocks) - 1] = -1
|
|
//vresult
|
|
vresult := &AliyunAudioRecognitionResult{
|
|
Text:thisText,
|
|
ChannelId:channel,
|
|
BeginTime:beginTime,
|
|
EndTime:w.EndTime,
|
|
SilenceDuration:w.SilenceDuration,
|
|
SpeechRate:w.SpeechRate,
|
|
EmotionValue:w.EmotionValue,
|
|
}
|
|
|
|
//fmt.Println( thisText )
|
|
//fmt.Println( block )
|
|
//fmt.Println( word.Word , beginTime, w.EndTime , flag , word.EndTime )
|
|
|
|
callback(vresult) //回调传参
|
|
|
|
//覆盖下一段落的时间戳
|
|
if windex < (len(p)-1) {
|
|
beginTime = p[windex+1].BeginTime
|
|
} else {
|
|
beginTime = w.EndTime
|
|
}
|
|
|
|
//清除参数
|
|
block = ""
|
|
lastBlock = 0
|
|
}
|
|
} else {
|
|
|
|
//清除参数
|
|
block = ""
|
|
lastBlock = 0
|
|
blockBool = true
|
|
|
|
if w.BlockEmptyHandle == false {
|
|
vresult := &AliyunAudioRecognitionResult{
|
|
Text:w.Text,
|
|
ChannelId:w.ChannelId,
|
|
BeginTime:w.BeginTime,
|
|
EndTime:w.EndTime,
|
|
SilenceDuration:w.SilenceDuration,
|
|
SpeechRate:w.SpeechRate,
|
|
EmotionValue:w.EmotionValue,
|
|
}
|
|
callback(vresult) //回调传参
|
|
w.BlockEmptyHandle = true
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func FindSliceIntCount(slice []int , target int) int {
|
|
c := 0
|
|
for _ , v := range slice {
|
|
if target == v {
|
|
c++
|
|
}
|
|
}
|
|
return c
|
|
}
|
|
|
|
|
|
//批量替换多个关键词文本
|
|
func ReplaceStrs(strs string , olds []string , s string) string {
|
|
for _ , word := range olds {
|
|
strs = strings.Replace(strs , word , s , -1)
|
|
}
|
|
return strs
|
|
}
|
|
|
|
func StringIndex(strs string , word rune) int {
|
|
strsRune := []rune(strs)
|
|
for i,v := range strsRune {
|
|
if v == word {
|
|
return i
|
|
}
|
|
}
|
|
return -1
|
|
}
|
|
|
|
//补全右边空格
|
|
func CompleSpace(s string) string {
|
|
s = strings.TrimLeft(s , " ");
|
|
s = strings.TrimRight(s , " ");
|
|
return s + " ";
|
|
}
|
|
|
|
func IsChineseWords(words []*AliyunAudioWord) bool {
|
|
for _,v := range words {
|
|
if (IsChineseChar(v.Word)){
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func IsChineseChar(str string) bool {
|
|
for _, r := range str {
|
|
if unicode.Is(unicode.Scripts["Han"], r) || (regexp.MustCompile("[\u3002\uff1b\uff0c\uff1a\u201c\u201d\uff08\uff09\u3001\uff1f\u300a\u300b]").MatchString(string(r))) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func IndexRunes(strs string , olds []rune) int {
|
|
min := -1
|
|
for i , word := range olds {
|
|
index := StringIndex(strs , word)
|
|
//println( "ts : " , index)
|
|
if i == 0 {
|
|
min = index
|
|
} else {
|
|
if min == -1 {
|
|
min = index
|
|
} else {
|
|
if index < min && index != -1 {
|
|
min = index
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return min
|
|
}
|
|
|
|
func GetTextBlock(strs string) ([]int) {
|
|
var symbol_zhcn = []rune{'?','。',',','!',';','、','?','.',',','!'}
|
|
//var symbol_en = []rune{'?','.',',','!'}
|
|
strsRune := []rune(strs)
|
|
|
|
blocks := []int{}
|
|
for {
|
|
index := IndexRunes(strs , symbol_zhcn)
|
|
if index == -1 {
|
|
break
|
|
}
|
|
strs = string(strsRune[0:index]) + string(strsRune[(index + 1):])
|
|
strsRune = []rune(strs)
|
|
blocks = append(blocks , index)
|
|
}
|
|
return blocks
|
|
}
|
|
|
|
|
|
func SubString(str string , begin int ,length int) (substr string) {
|
|
// 将字符串的转换成[]rune
|
|
rs := []rune(str)
|
|
lth := len(rs)
|
|
|
|
// 简单的越界判断
|
|
if begin < 0 {
|
|
begin = 0
|
|
}
|
|
if begin >= lth {
|
|
begin = lth
|
|
}
|
|
if length < 0 {
|
|
length = 0
|
|
}
|
|
end := begin + length
|
|
if end > lth {
|
|
end = lth
|
|
}
|
|
// 返回子串
|
|
return string(rs[begin:end])
|
|
}
|
|
|
|
|
|
//过滤文本
|
|
func FilterText(text string) string {
|
|
//去除换行符
|
|
re, _ := regexp.Compile("[\n|\r|\r\n]+")
|
|
text = re.ReplaceAllString(text, "")
|
|
return text
|
|
}
|