Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
C
CharIP-Electron
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ali
CharIP-Electron
Commits
83ceae1a
Commit
83ceae1a
authored
Dec 25, 2023
by
ali
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 照片数字人直播切换到sdk 接口方案
parent
d32e1cdc
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
97 additions
and
25 deletions
+97
-25
package-lock.json
package-lock.json
+6
-0
package.json
package.json
+3
-2
HeaderLayout.vue
src/renderer/components/layout/HeaderLayout.vue
+5
-4
PhotoRole.ts
src/renderer/plugins/live/PhotoRole.ts
+48
-18
settings.ts
src/renderer/store/settings.ts
+1
-1
jwt.ts
src/renderer/utils/jwt.ts
+34
-0
No files found.
package-lock.json
View file @
83ceae1a
...
...
@@ -10,6 +10,7 @@
"license"
:
"MIT"
,
"dependencies"
:
{
"axios"
:
"^1.6.2"
,
"crypto-js"
:
"^4.1.1"
,
"electron-store"
:
"^8.1.0"
,
"EventEmitter"
:
"^1.0.0"
,
"flv.js"
:
"^1.6.2"
,
...
...
@@ -3911,6 +3912,11 @@
"node"
:
">= 8"
}
},
"node_modules/crypto-js"
:
{
"version"
:
"4.2.0"
,
"resolved"
:
"https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz"
,
"integrity"
:
"sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"node_modules/css"
:
{
"version"
:
"2.2.4"
,
"resolved"
:
"https://registry.npmmirror.com/css/-/css-2.2.4.tgz"
,
...
...
package.json
View file @
83ceae1a
...
...
@@ -41,7 +41,8 @@
"
vue
"
:
"^3.3.7"
,
"
vue-i18n
"
:
"^9.6.2"
,
"
vue-router
"
:
"^4.2.5"
,
"
vuetify
"
:
"^3.3.23"
"
vuetify
"
:
"^3.3.23"
,
"
crypto-js
"
:
"^4.1.1"
},
"devDependencies"
:
{
"
@mdi/font
"
:
"^7.3.67"
,
...
...
src/renderer/components/layout/HeaderLayout.vue
View file @
83ceae1a
...
...
@@ -64,10 +64,11 @@ const asrItems = ref([
// 'Whisper Api'
])
const
liveHosts
=
ref
([
'http://111.229.216.162:9000'
,
'http://124.221.182.173:9000'
,
'http://110.42.214.59:9000'
,
'http://122.51.32.12:9000'
'laihua'
,
// 'http://111.229.216.162:9000',
// 'http://124.221.182.173:9000',
// 'http://110.42.214.59:9000',
// 'http://122.51.32.12:9000'
])
const
asrSelect
=
ref
(
setting
.
asr
)
...
...
src/renderer/plugins/live/PhotoRole.ts
View file @
83ceae1a
/* eslint-disable camelcase */
import
http
from
'@/renderer/utils/http'
import
http
,
{
axiosInstance
}
from
'@/renderer/utils/http'
import
{
JWT
}
from
'@/renderer/utils/jwt'
;
import
{
HwWebRTC
}
from
'./HwWebRTC'
import
{
guid
}
from
'@/renderer/utils/index'
import
EventEmitter
from
'EventEmitter'
...
...
@@ -11,14 +12,20 @@ type LiveOptions = {
audioUrl
?:
string
|
null
taskId
:
string
imgUrl
:
string
pushUrl
:
string
pullUrl
:
string
pushUrl
?
:
string
pullUrl
?
:
string
speed
?:
number
bitrate
:
number
superres
:
boolean
isLast
:
boolean
}
type
SdkConfigDataParams
=
{
baseUrl
:
string
;
baseSocketUrl
:
string
;
};
export
class
PhotoAnswer
{
question
=
''
answer
=
''
...
...
@@ -65,7 +72,7 @@ export type PhotoEventTypeFn<T extends PhotoEventType> = {
}[
T
]
export
class
PhotoRole
extends
EventEmitter
{
readonly
host
:
string
private
host
:
string
readonly
view
:
HTMLCanvasElement
readonly
ctx
:
CanvasRenderingContext2D
private
_webRTCContainer
:
HTMLDivElement
=
document
.
createElement
(
'div'
)
...
...
@@ -109,10 +116,10 @@ export class PhotoRole extends EventEmitter {
this
.
_liveTaskQueue
.
push
({
imgUrl
:
this
.
url
,
taskId
,
pushUrl
:
`rtmp://push.laihua.com/web/
${
taskId
}
`
,
pullUrl
:
`webrtc://pull.laihua.com/web/
${
taskId
}
`
,
speaker
:
'
speaker
'
,
languageCode
:
'zh
-CN
'
,
//
pushUrl: `rtmp://push.laihua.com/web/${taskId}`,
//
pullUrl: `webrtc://pull.laihua.com/web/${taskId}`,
speaker
:
'
101015
'
,
languageCode
:
'zh
_cn
'
,
audioUrl
,
speed
:
10
,
bitrate
:
2000
,
...
...
@@ -224,7 +231,7 @@ export class PhotoRole extends EventEmitter {
const
resp
=
(
await
http
({
method
:
'POST'
,
url
:
`
${
this
.
host
}
/
creat
e`
,
url
:
`
${
this
.
host
}
/
liv
e`
,
data
:
{
...
options
}
// ip: 'http://116.63.168.14:9000'
}))
as
{
code
:
number
...
...
@@ -254,7 +261,7 @@ export class PhotoRole extends EventEmitter {
private
async
_appendLive
(
options
:
LiveOptions
)
{
const
resp
=
(
await
http
({
method
:
'POST'
,
url
:
`
${
this
.
host
}
/append`
,
url
:
`
${
this
.
host
}
/
live/
append`
,
data
:
{
...
options
}
// ip: 'http://116.63.168.14:9000'
}))
as
{
code
:
number
...
...
@@ -284,7 +291,7 @@ export class PhotoRole extends EventEmitter {
private
async
_pushLive
(
taskId
:
string
)
{
const
resp
=
(
await
http
({
method
:
'POST'
,
url
:
`
${
this
.
host
}
/push`
,
url
:
`
${
this
.
host
}
/
live/
push`
,
data
:
{
taskId
}
}))
as
{
code
:
number
...
...
@@ -302,7 +309,7 @@ export class PhotoRole extends EventEmitter {
private
async
_getLiveStatus
(
taskId
:
string
)
{
const
resp
=
(
await
http
({
method
:
'GET'
,
url
:
`
${
this
.
host
}
/
s
tatus`
,
url
:
`
${
this
.
host
}
/
live/validateS
tatus`
,
params
:
{
taskId
}
}))
as
{
code
:
number
...
...
@@ -355,20 +362,20 @@ export class PhotoRole extends EventEmitter {
async
initLive
()
{
console
.
time
(
'init'
)
console
.
time
(
'
init-
_createLive'
)
console
.
time
(
'_createLive'
)
const
{
pullUrl
,
taskId
,
imgInfo
}
=
await
this
.
_createLive
({
imgUrl
:
this
.
url
,
pushUrl
:
`rtmp://push.laihua.com/web/
${
this
.
sessionId
}
`
,
pullUrl
:
`webrtc://pull.laihua.com/web/
${
this
.
sessionId
}
`
,
//
pushUrl: `rtmp://push.laihua.com/web/${this.sessionId}`,
//
pullUrl: `webrtc://pull.laihua.com/web/${this.sessionId}`,
taskId
:
this
.
sessionId
,
speaker
:
'
speaker
'
,
languageCode
:
'zh
-CN
'
,
speaker
:
'
101015
'
,
languageCode
:
'zh
_cn
'
,
audioUrl
:
''
,
bitrate
:
2000
,
superres
:
false
,
isLast
:
true
})
console
.
timeEnd
(
'
init-
_createLive'
)
console
.
timeEnd
(
'_createLive'
)
this
.
_rtcVideoInfo
=
imgInfo
console
.
time
(
'play'
)
...
...
@@ -454,10 +461,33 @@ export class PhotoRole extends EventEmitter {
this
.
_rtc
=
new
HwWebRTC
(
this
.
_webRTCContainer
.
id
)
this
.
_bindEvents
()
if
(
this
.
host
===
'laihua'
)
{
this
.
host
=
await
this
.
auth
();
}
await
this
.
initLive
()
// this._pollStatus(this.sessionId);
}
async
auth
()
{
const
token
=
JWT
.
encode
(
JSON
.
stringify
({
appId
:
'88ca56ac88257f14'
,
iat
:
new
Date
().
getTime
()
+
1000
*
30
}),
'92b39dd13b952bcd4ce1995473cc3302'
);
axiosInstance
.
defaults
.
headers
.
common
.
Authorization
=
`Bearer
${
token
}
`
;
const
res
=
await
http
({
url
:
'https://openapi.laihua.com/sdk/getConfig'
});
const
{
code
,
data
}
=
res
as
{
code
:
number
|
string
;
data
:
SdkConfigDataParams
|
string
;
};
if
(
code
!==
200
)
{
throw
new
Error
(
`
${
code
}
:
${
JSON
.
stringify
(
res
)
}
`
);
}
return
(
data
as
SdkConfigDataParams
).
baseUrl
;
}
destroy
()
{
this
.
_webRTCContainer
&&
document
.
body
.
removeChild
(
this
.
_webRTCContainer
)
this
.
_rtc
?.
stopPlay
()
...
...
src/renderer/store/settings.ts
View file @
83ceae1a
...
...
@@ -66,7 +66,7 @@ const useSettingsStore = defineStore('settings', {
llmUrl
:
'ws://127.0.0.1:9899/api/v1/stream'
,
llmToTTSSliceLength
:
20
,
voskWsLUrl
:
'ws://127.0.0.1:2700'
,
liveHost
:
'
http://122.51.32.12:9000
'
,
liveHost
:
'
laihua
'
,
vConsole
:
true
})
as
ISettings
,
getters
:
{},
...
...
src/renderer/utils/jwt.ts
0 → 100644
View file @
83ceae1a
import
CryptoJS
from
'crypto-js'
;
export
class
JWT
{
static
sign
(
content
:
string
,
secret
:
string
)
{
const
r
=
CryptoJS
.
HmacSHA256
(
content
,
secret
);
const
b
=
CryptoJS
.
enc
.
Base64
.
stringify
(
r
);
return
this
.
base64urlEscape
(
b
);
}
static
base64urlEscape
(
str
:
string
)
{
return
str
.
replace
(
/
\+
/g
,
'-'
).
replace
(
/
\/
/g
,
'_'
).
replace
(
/=/g
,
''
);
}
static
toBase64
(
content
:
string
)
{
return
btoa
(
content
);
}
static
encode
(
username
:
string
,
secret
:
string
)
{
const
header
=
this
.
toBase64
(
JSON
.
stringify
({
typ
:
'JWT'
,
alg
:
'HS256'
}));
const
content
=
this
.
toBase64
(
username
);
const
sign
=
this
.
sign
([
header
,
content
].
join
(
'.'
),
secret
);
return
[
header
,
content
,
sign
].
join
(
'.'
);
}
static
decode
(
token
:
string
,
secret
:
string
)
{
const
[
header
,
content
,
sign
]
=
token
.
split
(
'.'
);
const
newSign
=
this
.
sign
([
header
,
content
].
join
(
'.'
),
secret
);
if
(
sign
===
newSign
)
{
return
atob
(
content
);
}
else
{
throw
new
Error
(
'被篡改'
);
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment