Skip to content

Commit 9c981b2

Browse files
committed
Merge branch 'main' into dev
2 parents 3b3d0fe + 52b4582 commit 9c981b2

24 files changed

+111
-58
lines changed

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ We always adhere to the open source spirit, and the launch of the API service ai
4141
[**Android Version**](https://github.com/GuijiAI/duix.ai/blob/main/duix-android/dh_aigc_android/README.md) |
4242
[**IOS Version**](https://github.com/GuijiAI/duix.ai/blob/main/duix-ios/GJLocalDigitalDemo/GJLocalDigitalSDK.md)
4343

44-
<img src="./README_zh.assets/1CB5196D-C989-4577-8C57-DCBA3E0871B2-51277-000008CE6CF0B87B.jpg" width="50%">
44+
<img src="./README_zh.assets/cb10263a14cc826e22c2be4bcae01a89.jpg" width="50%">
4545

4646
## Open Source Co-Creation · Shared Glory
4747

@@ -86,6 +86,10 @@ Since we open-sourced Heygem, global geeks have illuminated the digital avatar m
8686

8787
[AI Digital Humans Are Free! GitHub's Hot Project Can Run on Your Computer](http://xhslink.com/a/8UT1kQ7vxjh8)
8888

89+
[The Most Popular Free AI Digital Human, HeyGem V1.0.3, Latest Update, One-Click Integration Package! Super Strong Lip-Sync Effect, Speed Up, Supports Long Videos, Batch Generation, 8G Video Memory Available!](https://www.bilibili.com/video/BV1SkoCYpEwh/?share_source=copy_web&vd_source=c38dcdb72a68f2a4e0b3c0f4f9a5a03c)
90+
91+
[**HeyGem One-Click Package Windows Direct Run Without Docker Silicon-Based Open Source Digital Human**](https://www.bilibili.com/video/BV1ZgovYGE3u/)
92+
8993
## Introduction
9094

9195
<img src="README_zh.assets/image-20250304114114272.png">
@@ -334,3 +338,7 @@ Interface: `http://127.0.0.1:18180/v1/invoke`
334338

335339
- ASR based on [fun-asr](https://github.com/modelscope/FunASR)
336340
- TTS based on [fish-speech-ziming](https://github.com/fishaudio/fish-speech)
341+
342+
## Star History
343+
344+
[![Star History Chart](https://api.star-history.com/svg?repos=GuijiAI/HeyGem.ai&type=Date)](https://www.star-history.com/#GuijiAI/HeyGem.ai&Date)
Binary file not shown.
Binary file not shown.
Loading

README_zh.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
[**Android版本**](https://github.com/GuijiAI/duix.ai/blob/main/duix-android/dh_aigc_android/README.md) |
4242
[**IOS版本**](https://github.com/GuijiAI/duix.ai/blob/main/duix-ios/GJLocalDigitalDemo/GJLocalDigitalSDK.md)
4343

44-
<img src="./README_zh.assets/1CB5196D-C989-4577-8C57-DCBA3E0871B2-51277-000008CE6CF0B87a.jpg" width="50%">
44+
<img src="./README_zh.assets/cb10263a14cc826e22c2be4bcae01a89.jpg" width="50%">
4545

4646

4747
## 【开源共创·荣耀共享】
@@ -87,6 +87,10 @@
8787

8888
[AI数字人免费啦!GitHub爆火项目电脑就能跑](http://xhslink.com/a/8UT1kQ7vxjh8)
8989

90+
[最火爆免费AI数字人,HeyGem V1.0.3,最新更新,一键整合包!口型效果超强,速度飞起,支持长视频、批量生成,8G显存可用!](https://www.bilibili.com/video/BV1SkoCYpEwh/?share_source=copy_web&vd_source=c38dcdb72a68f2a4e0b3c0f4f9a5a03c)
91+
92+
[【HeyGem】一键包 windows直接运行 无需docker 硅基开源数字人](https://www.bilibili.com/video/BV1ZgovYGE3u/)
93+
9094
## 介绍
9195

9296
<img src="README_zh.assets/image-20250304114114272.png">
@@ -397,3 +401,7 @@ docker-compose -f docker-compose-linux.yml up -d
397401
398402
- ASR 基于 [fun-asr](https://github.com/modelscope/FunASR)
399403
- TTS 基于 [fish-speech-ziming](https://github.com/fishaudio/fish-speech)
404+
405+
## Star History
406+
407+
[![Star History Chart](https://api.star-history.com/svg?repos=GuijiAI/HeyGem.ai&type=Date)](https://www.star-history.com/#GuijiAI/HeyGem.ai&Date)
Loading
Binary file not shown.

doc/常见问题.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,28 @@
5252
- Docker Hub 官方源连接不稳定,您需要打开VPN的全局模式
5353
5454
- 或者使用国内镜像源,如下图设置
55-
![image-20250311145333297](常见问题.assets/image-20250311145333297.png)
56-
5755
56+
![2025-03-25_09-36-07](./常见问题.assets/2025-03-25_09-36-07.jpg)
57+
```json
58+
{
59+
"builder": {
60+
"gc": {
61+
"defaultKeepStorage": "20GB",
62+
"enabled": true
63+
}
64+
},
65+
"experimental": false,
66+
"registry-mirrors": [
67+
"https://docker.zhai.cm",
68+
"https://a.ussh.net",
69+
"https://hub.littlediary.cn",
70+
"https://hub.rat.dev",
71+
"https://atomhub.openatom.cn",
72+
"https://docker.m.daocloud.io",
73+
"https://docker.1ms.run"
74+
]
75+
}
76+
```
5877
5978
2. 新增模特时报错如下图:
6079

src/main/handlers/file.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ export default {
2929
},
3030
async getVideoInfo(app, videoPath) {
3131
return new Promise((resolve) => {
32+
videoPath = videoPath.replace(/^file:\/\//, '')
3233
ffmpeg(videoPath).ffprobe((err, data) => {
3334
if (err) {
3435
resolve({ isOK: false, msg: err.toString() })
@@ -42,6 +43,7 @@ export default {
4243
},
4344

4445
async getAudioInfo(app, audioPath) {
46+
audioPath = audioPath.replace(/^file:\/\//, '')
4547
return new Promise((resolve) => {
4648
ffmpeg(audioPath).ffprobe((err, data) => {
4749
if (err) {

src/main/util/ffmpeg.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ function initFFmpeg() {
3030
}
3131

3232
const ffmpegPathValue = ffmpegPath[`${process.env.NODE_ENV}-${process.platform}`]
33+
log.debug('ENV:', `${process.env.NODE_ENV}-${process.platform}`)
3334
log.info('FFmpeg path:', ffmpegPathValue)
3435
ffmpeg.setFfmpegPath(ffmpegPathValue)
3536

src/renderer/src/api/index.js

Lines changed: 8 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
import { localUrl } from '@renderer/utils'
21

3-
export async function videoPage({ page = 1, pageSize = 1, name = '' }) {
4-
const result = await window.electron.ipcRenderer.invoke('video/page', { page, pageSize, name })
5-
result.list = (result.list || []).map(model=>{
6-
model.file_path = localUrl.addFileProtocol(model.file_path)
7-
return model
8-
})
9-
return result
2+
3+
export function videoPage({ page = 1, pageSize = 1, name = '' }) {
4+
return window.electron.ipcRenderer.invoke('video/page', { page, pageSize, name })
105
}
116

127
export function findVideo(id) {
@@ -18,8 +13,6 @@ export function removeVideo(id) {
1813
}
1914

2015
export function saveVideo(video) {
21-
// id, model_id, name, text_content, voice_id, audio_path
22-
video.audio_path = localUrl.delFileProtocol(video.audio_path)
2316
return window.electron.ipcRenderer.invoke('video/save', video)
2417
}
2518

@@ -39,25 +32,16 @@ export function countVideo(name = '') {
3932
return window.electron.ipcRenderer.invoke('video/count', name)
4033
}
4134

42-
export async function modelPage({ page = 1, pageSize = 1, name = '' }) {
43-
const result = await window.electron.ipcRenderer.invoke('model/page', { page, pageSize, name })
44-
result.list = (result.list || []).map(model=>{
45-
model.video_path = localUrl.addFileProtocol(model.video_path)
46-
return model
47-
})
48-
return result
35+
export function modelPage({ page = 1, pageSize = 1, name = '' }) {
36+
return window.electron.ipcRenderer.invoke('model/page', { page, pageSize, name })
37+
4938
}
5039

51-
export async function findModel(id) {
52-
const result = await window.electron.ipcRenderer.invoke('model/find', id)
53-
if(result){
54-
result.video_path = localUrl.addFileProtocol(result.video_path)
55-
}
56-
return result
40+
export function findModel(id) {
41+
return window.electron.ipcRenderer.invoke('model/find', id)
5742
}
5843

5944
export function addModel({ name, videoPath }) {
60-
videoPath = localUrl.delFileProtocol(videoPath)
6145
return window.electron.ipcRenderer.invoke('model/addModel', name, videoPath)
6246
}
6347

src/renderer/src/client/index.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import { localUrl } from "@renderer/utils"
21

32
export const Client = {
43
file: {
54
...window.client.file,
6-
selectFile: async (filter = {}) => {
7-
const filePath = await window.client.file.selectFile(filter)
8-
return localUrl.addFileProtocol(filePath)
5+
selectFile: (filter = {}) => {
6+
return window.client.file.selectFile(filter)
97
},
108
selectImage: async () => {
119
return Client.file.selectFile({ name: 'Images', extensions: ['jpg', 'png', 'jpeg'] })

src/renderer/src/components/model-create/ModalBoxUpload.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
<!-- 已上传 -->
99
<div class="upload-box --uploaded" v-else-if="uploadInfo.videoPath" @click="action.upload">
10-
<video class="video" :src="uploadInfo.videoPath" controls />
10+
<video class="video" :src="localUrl.addFileProtocol(uploadInfo.videoPath)" controls />
1111
</div>
1212

1313
<!-- 未上传 -->
@@ -25,7 +25,7 @@ import { reactive } from 'vue'
2525
import ImageShotVideo from '@renderer/assets/images/create-model/image-shot.png'
2626
import { Client } from '@renderer/client'
2727
import { MessagePlugin } from 'tdesign-vue-next'
28-
28+
import { localUrl } from '@renderer/utils'
2929
3030
import { useI18n } from 'vue-i18n'
3131
const { t } = useI18n()

src/renderer/src/i18n/components/common.js

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,20 @@ export const commonZh = {
112112
headerText: '画面预览'
113113
},
114114
editView: {
115-
headerText: '视频内容'
115+
headerText: '视频内容',
116+
text: '文本合成',
117+
audio: '音频合成',
118+
addAudio: '添加音频',
119+
tip: '单次最多上传1个录音文件;支持mp3、wav、flac、m4a文件,单个录音时长小于30分钟,请上传纯干音文件,背景音、噪音会影响视频合成效果哦~',
120+
listen: '试听',
121+
delete: '删除',
122+
upload: '上传',
123+
uploadError: '音频上传失败',
124+
durationError: '音频时长不能超过30分钟',
125+
myVoice: '我的',
126+
selectSpeaker: '选择',
127+
speaker: '音色',
128+
searchSpeaker: '搜索音色'
116129
},
117130
headerView: {
118131
headerBackText: '返回',
@@ -239,7 +252,20 @@ export const commonEn = {
239252
headerText: 'Preview'
240253
},
241254
editView: {
242-
headerText: 'Content'
255+
headerText: 'Content',
256+
text: 'Text Synthesis',
257+
audio: 'Audio Synthesis',
258+
addAudio: 'Add Audio',
259+
tip: 'You can upload up to 1 audio file at a time; supports mp3, wav, flac, m4a files, each recording should be less than 30 minutes. Please upload pure dry audio files, as background noise and sounds will affect the video synthesis effect.',
260+
listen: 'Listen',
261+
delete: 'Delete',
262+
upload: 'Upload',
263+
uploadError: 'Audio Upload Failed',
264+
durationError: 'Audio duration cannot exceed 30 minutes',
265+
myVoice: 'My',
266+
selectSpeaker: 'Select',
267+
speaker: 'Speaker',
268+
searchSpeaker: 'Search Speaker'
243269
},
244270
headerView: {
245271
headerBackText: 'Back',

src/renderer/src/views/home/components/myModelList.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
<div class="img-video comme">
4242
<div class="img-video-content">
4343
<div class="duration" style="display: none">00:30</div>
44-
<video class="model-video" :src="item.video_path"></video>
44+
<video class="model-video" :src="localUrl.addFileProtocol(item.video_path)"></video>
4545
<div class="fail" style="display: none">
4646
<div class="fail-line"></div>
4747
<span> {{ $t('common.myModelList.inProgressText') }}</span>
@@ -118,6 +118,7 @@ import enConfig from 'tdesign-vue-next/es/locale/en_US'
118118
import zhConfig from 'tdesign-vue-next/es/locale/zh_CN'
119119
import { useI18n } from 'vue-i18n'
120120
const { locale,t } = useI18n()
121+
import { localUrl } from '@renderer/utils'
121122
122123
import merge from 'lodash/merge'
123124
const globalEn = merge(enConfig, {

src/renderer/src/views/home/components/videoDialog.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
ref="videoPlayer"
1515
class="video-look"
1616
autoplay
17-
:src="props.videoUrl"
17+
:src="localUrl.addFileProtocol(props.videoUrl)"
1818
controls
1919
></video>
2020
</div>
@@ -23,6 +23,7 @@
2323
</template>
2424
<script setup>
2525
import { ref } from "vue";
26+
import { localUrl } from '@renderer/utils'
2627
const emit = defineEmits(["cancel"]);
2728
const props = defineProps({
2829
showVideoDialog: Boolean,

src/renderer/src/views/home/components/worksList.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
{{ item.duration + '' ? millisecondsToTime(item.duration * 1000) : '00:00' }}
3434
</div>
3535
<div v-if="item.status === 'success'" class="works-video">
36-
<video :src="item.file_path"></video>
36+
<video :src="localUrl.addFileProtocol(item.file_path)"></video>
3737
</div>
3838
<!-- <video class="works-video" src="../../../assets/images/home/aa.mp4"></video> -->
3939
<img
@@ -169,6 +169,7 @@ import enConfig from 'tdesign-vue-next/es/locale/en_US'
169169
import zhConfig from 'tdesign-vue-next/es/locale/zh_CN'
170170
import { useI18n } from 'vue-i18n'
171171
const { locale, t } = useI18n()
172+
import { localUrl } from '@renderer/utils'
172173
173174
import merge from 'lodash/merge'
174175
const globalEn = merge(enConfig, {

src/renderer/src/views/video-edit/edit/EditListener.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import PlayIcon from '@renderer/assets/images/icons/icon-play.png'
2828
import PauseIcon from '@renderer/assets/images/icons/icon-pause.png'
2929
import { cloneDeep } from 'lodash-es';
3030
import { millisecondsToTime } from '@renderer/utils/index.js'
31+
import { localUrl } from '@renderer/utils'
3132
3233
const AUDIO_STATUS = {
3334
UNPLAY: 0,
@@ -113,7 +114,7 @@ const action = {
113114
114115
play(audioUrl) {
115116
if (audioUrl && audioUrl !== state.audioUrl) {
116-
audio.src = audioUrl
117+
audio.src = localUrl.addFileProtocol(audioUrl)
117118
state.audioUrl = audioUrl
118119
}
119120
audio.play()

src/renderer/src/views/video-edit/edit/EditText.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
<!-- 选择音色 -->
77
<div class="speaker">
88
<div class="speaker-content">
9-
<span class="label">音色</span>
9+
<span class="label">{{ $t('common.editView.speaker') }}</span>
1010
<t-popup trigger="click" overlayClassName="speaker-popup" placement="top-left"
1111
v-model:visible="state.popupVisible">
1212
<t-select class="selector" :value="select.speaker?.name"
13-
:popupProps="{ overlayClassName: 'speaker-options' }" placeholder="选择">
13+
:popupProps="{ overlayClassName: 'speaker-options' }" :placeholder="$t('common.editView.selectSpeaker')">
1414
</t-select>
1515
<template #content>
1616
<div class="popup-scoped">
17-
<div class="side">我的</div>
17+
<div class="side">{{ $t('common.editView.myVoice') }}</div>
1818
<EditTextSpeaker class="wrap" v-model="select" @onSelect="action.onSelectSpeaker"
1919
:popupVisible="state.popupVisible" />
2020
</div>
@@ -23,7 +23,7 @@
2323
</div>
2424
</div>
2525
<!-- 试听 -->
26-
<t-button class="start" size="small" @click="action.textToAudio" :loading="state.textToAudioLoading">试听</t-button>
26+
<t-button class="start" size="small" @click="action.textToAudio" :loading="state.textToAudioLoading">{{ $t('common.editView.listen') }}</t-button>
2727
</div>
2828
</div>
2929
</template>

src/renderer/src/views/video-edit/edit/EditTextSpeaker.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
<template>
22
<div class="list">
33
<!-- 搜索框 -->
4-
<t-input class="list-search" v-model="state.search" placeholder="搜索音色" @change="action.searchList">
4+
<t-input class="list-search" v-model="state.search" :placeholder="$t('common.editView.searchSpeaker')"
5+
@change="action.searchList">
56
<template #prefix-icon>
67
<SearchIcon />
78
</template>

0 commit comments

Comments
 (0)