Skip to content

Commit

Permalink
v2.19.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Dooy committed Jul 6, 2024
1 parent 62c9ab5 commit f59e27f
Show file tree
Hide file tree
Showing 26 changed files with 887 additions and 12 deletions.
3 changes: 3 additions & 0 deletions changlog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# 功能升级日志

# 计划
# 2.19.2
- 😄 新增:跳舞视频viggle模块

# 2.19.1
- 🐞 修复:Luma下载按钮无法下载? #443
- 🐞 修复:luma pro 与 relax版本切换 获取任务有问题
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chatgpt-web-midjourney-proxy",
"version": "2.19.1",
"version": "2.19.2",
"private": false,
"description": "ChatGPT Web Midjourney Proxy",
"author": "Dooy <[email protected]>",
Expand Down
22 changes: 22 additions & 0 deletions service/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import FormData from 'form-data'
import axios from 'axios';
import AWS from 'aws-sdk';
import { v4 as uuidv4} from 'uuid';
import { viggleProxyFileDo } from './myfun'


const app = express()
Expand Down Expand Up @@ -348,6 +349,27 @@ app.use('/luma' ,authV2, proxy(process.env.LUMA_SERVER?? API_BASE_URL, {
}));


app.use('/viggle/asset',authV2 , upload2.single('file'), viggleProxyFileDo );
//代理luma 接口
app.use('/viggle' ,authV2, proxy(process.env.VIGGLE_SERVER?? API_BASE_URL, {
https: false, limit: '10mb',
proxyReqPathResolver: function (req) {
return req.originalUrl //req.originalUrl.replace('/sunoapi', '') // 将URL中的 `/openapi` 替换为空字符串
},
proxyReqOptDecorator: function (proxyReqOpts, srcReq) {
//mlog("sunoapi")
if ( process.env.VIGGLE_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.VIGGLE_KEY;
else proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;
proxyReqOpts.headers['Content-Type'] = 'application/json';
proxyReqOpts.headers['Mj-Version'] = pkg.version;
return proxyReqOpts;
},

}));




app.use('', router)
app.use('/api', router)
app.set('trust proxy', 1)
Expand Down
40 changes: 40 additions & 0 deletions service/src/myfun.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import axios from 'axios';
import { Request, Response, NextFunction } from 'express';
import { isNotEmptyString } from './utils/is';
import FormData from 'form-data'


//req, res, next

export const viggleProxyFileDo= async( req:Request, res:Response, next?:NextFunction)=>{
// if ( process.env.VIGGLE_KEY ) proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.VIGGLE_KEY;
// else proxyReqOpts.headers['Authorization'] ='Bearer '+process.env.OPENAI_API_KEY;
console.log('req.originalUrl', req.originalUrl );
let API_BASE_URL = isNotEmptyString(process.env.OPENAI_API_BASE_URL)
? process.env.OPENAI_API_BASE_URL
: 'https://api.openai.com'
API_BASE_URL= process.env.VIGGLE_SERVER?? API_BASE_URL
if(req.file.buffer) {
const fileBuffer = req.file.buffer;
const formData = new FormData();
formData.append('file', fileBuffer, { filename: req.file.originalname } );
// formData.append('model', req.body.model );
try{
let url = `${API_BASE_URL}${req.originalUrl}` ;
let responseBody = await axios.post( url , formData, {
headers: {
Authorization: 'Bearer '+ (process.env.VIGGLE_KEY??process.env.OPENAI_API_KEY) ,
'Content-Type': 'multipart/form-data',
//'Mj-Version': pkg.version
}
}) ;
res.json(responseBody.data );
}catch(e){
res.status( 400 ).json( {error: e } );
}

}else{
res.status(400).json({'error':'uploader fail'});
}

}
2 changes: 1 addition & 1 deletion src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"package": {
"productName": "ChatGPT-MJ",
"version": "2.19.1"
"version": "2.19.2"
},
"tauri": {
"allowlist": {
Expand Down
138 changes: 138 additions & 0 deletions src/api/viggle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import { gptServerStore, homeStore, useAuthStore } from "@/store";
import { mlog } from "./mjapi";
import { sleep } from "./suno";
import { ViggleTask, viggleStore } from "./viggleStore";

function getHeaderAuthorization(){
let headers={}
if( homeStore.myData.vtoken ){
const vtokenh={ 'x-vtoken': homeStore.myData.vtoken ,'x-ctoken': homeStore.myData.ctoken};
headers= {...headers, ...vtokenh}
}
if(!gptServerStore.myData.VIGGLE_KEY){
const authStore = useAuthStore()
if( authStore.token ) {
const bmi= { 'x-ptoken': authStore.token };
headers= {...headers, ...bmi }
return headers;
}
return headers
}
const bmi={
'Authorization': 'Bearer ' +gptServerStore.myData.VIGGLE_KEY
}
headers= {...headers, ...bmi }
return headers
}

export const getUrl=(url:string)=>{
if(url.indexOf('http')==0) return url;

const pro_prefix= '';//url.indexOf('/pro')>-1?'/pro':'';//homeStore.myData.is_luma_pro?'/pro':''
// url= url.replaceAll('/pro','')
if(gptServerStore.myData.VIGGLE_SERVER){
if(gptServerStore.myData.VIGGLE_SERVER.indexOf('/pro')>0){
return `${ gptServerStore.myData.VIGGLE_SERVER}/viggle${url}`;
}
return `${ gptServerStore.myData.VIGGLE_SERVER}${pro_prefix}/viggle${url}`;
}
return `${pro_prefix}/viggle${url}`;
}

export interface tagInfo {
id: string;
name: string;
sort: number;
}
export interface ViggleTemplate {
id: string;
processedURL: string;
processedHdURL: string;
processedCoverURL: string;
command?: string;
webCommand?: string;
description: string;
webStatus?: number;
dcStatus?: number;
appStatus?: number;
bgURL?: string;
bgCoverURL?: string;
displayURL?: string;
displayHdURL?: string;
displayCoverURL?: string;
gifURL?: string;
webPURL?: string;
source?: string;
sort?: number;
width?: number;
height?: number;
}

export const viggleFetch=(url:string,data?:any,opt2?:any )=>{
mlog('viggleFetch', url );
let headers= opt2?.upFile?{}: {'Content-Type':'application/json'}

if(opt2 && opt2.headers ) headers= opt2.headers;

headers={...headers,...getHeaderAuthorization()}

return new Promise<any>((resolve, reject) => {
let opt:RequestInit ={method:'GET'};

opt.headers= headers ;
if(opt2?.upFile ){
opt.method='POST';
opt.body=data as FormData ;
}
else if(data) {
opt.body= JSON.stringify(data) ;
opt.method='POST';
}
fetch(getUrl(url), opt )
.then( async (d) =>{
if (!d.ok) {
let msg = '发生错误: '+ d.status
try{
let bjson:any = await d.json();
msg = '('+ d.status+')发生错误: '+(bjson?.error?.message??'' )
}catch( e ){
}
homeStore.myData.ms && homeStore.myData.ms.error(msg )
throw new Error( msg );
}

d.json().then(d=> resolve(d)).catch(e=>{

homeStore.myData.ms && homeStore.myData.ms.error('发生错误'+ e )
reject(e)
}
)})
.catch(e=>{
if (e.name === 'TypeError' && e.message === 'Failed to fetch') {
homeStore.myData.ms && homeStore.myData.ms.error('跨域|CORS error' )
}
else homeStore.myData.ms && homeStore.myData.ms.error('发生错误:'+e )
mlog('e', e.stat )
reject(e)
})
})

}

export async function FeedViggleTask(id:string){
const ss = new viggleStore()
for(let i=0; i<500;i++){
const d= await viggleFetch('/video-task/by-ids',{ids:[id]})
mlog('FeedViggleTask', d )

if(d.data && d.data.length>0){
let task= d.data[0] as ViggleTask;
task.last_feed=new Date().getTime()
ss.save( task )
homeStore.setMyData({act:'FeedViggleTask'})
if ( d.data[0].status==0) return
}
await sleep(2000)
}

}
49 changes: 49 additions & 0 deletions src/api/viggleStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { ss } from "@/utils/storage";

export interface ViggleTask {
taskID: string;
name: string;
status: number;
videoDuration: number;
bgMode: number;
modelInfoID: number;
optimize: boolean;
watermark: number;
freeCredits: number;
planCredits: number;
purchasedCredits: number;
mqType: number;
result: string;
resultCover: string;
createdAt: string;
last_feed:number;
}

export class viggleStore{
//private id: string;
private localKey='viggle-store';
public save(obj:ViggleTask ){
if(!obj.taskID ) throw "taskID must";
let arr= this.getObjs();
let i= arr.findIndex( v=>v.taskID==obj.taskID );
if(i>-1) arr[i]= obj;
else arr.push(obj);
ss.set(this.localKey, arr );
return this;
}
public findIndex(id:string){
return this.getObjs().findIndex( v=>v.taskID== id )
}

public getObjs():ViggleTask[]{
const obj = ss.get( this.localKey ) as undefined| ViggleTask[];
if(!obj) return [];
return obj;
}
public getOneById(id:string):ViggleTask|null{
const i= this.findIndex(id)
if(i<0) return null;
let arr= this.getObjs();
return arr[i]
}
}
22 changes: 22 additions & 0 deletions src/locales/en-US.ts
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,28 @@ export default {
download: 'Download',
extend: 'Extend'

},
dance:{
menu: "Dance",
menuinfo: "Create dance videos with Viggle and others.",
character: "Character",
viggleabout: "About Viggle",
viggleserver: "Viggle API Endpoint",
setOpenKeyPlaceholder: "Viggle API key, optional",
info: "Instructions:<br>1. Character images should preferably be full-body photos.<br>2. Dance template videos should be personal videos, not group dances.",
model: "Model",
bgw: "White Background",
bgg: "Green Background",
bgmoban: "Original Background",
bgrole: "Character Background",
gring: "Generating...",
uprolefirst: "Please upload character image first",
uprolefail: "Upload failed",
upvideo: "+ Upload Template Dance Video",
usevideo: "+ Use Official Template",
moban: "Dance Template",
moban2: "Template Name",
use: "Use"
}


Expand Down
22 changes: 22 additions & 0 deletions src/locales/fr-FR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,28 @@ export default {
"submitSuccess": "Soumis avec succès !",
"process": "Génération de la vidéo...",
"repeat": "Réessayer"
},
dance:{
menu: "Danse",
menuinfo: "Créez des vidéos de danse avec Viggle et d'autres.",
character: "Personnage",
viggleabout: "À propos de Viggle",
viggleserver: "Adresse API Viggle",
setOpenKeyPlaceholder: "Clé API Viggle, facultatif",
info: "Instructions :<br>1. Les images de personnage devraient de préférence être des photos en pied.<br>2. Les vidéos de modèles de danse devraient être des vidéos personnelles, pas des danses de groupe.",
model: "Modèle",
bgw: "Arrière-plan blanc",
bgg: "Arrière-plan vert",
bgmoban: "Arrière-plan du modèle",
bgrole: "Arrière-plan du personnage",
gring: "En cours de génération...",
uprolefirst: "Veuillez d'abord télécharger l'image du personnage",
uprolefail: "Échec du téléchargement",
upvideo: "+ Télécharger la vidéo de modèle de danse",
usevideo: "+ Utiliser le modèle officiel",
moban: "Modèle de danse",
moban2: "Nom du modèle",
use: "Utiliser"
}

}
24 changes: 23 additions & 1 deletion src/locales/ko-KR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,28 @@ export default {
"submitSuccess": "성공적으로 제출되었습니다!",
"process": "비디오 생성 중...",
"repeat": "재시도"
}
},
dance:{
menu: "댄스",
menuinfo: "Viggle 및 기타와 함께 댄스 비디오 제작",
character: "캐릭터",
viggleabout: "Viggle 소개",
viggleserver: "Viggle API 엔드포인트",
setOpenKeyPlaceholder: "Viggle API 키, 선택 사항",
info: "지침:<br>1. 캐릭터 이미지는 전신 사진이 좋습니다.<br>2. 댄스 템플릿 비디오는 개인 비디오여야 하며, 그룹 댄스가 아니어야 합니다.",
model: "모델",
bgw: "백색 배경",
bgg: "초록색 배경",
bgmoban: "템플릿 배경",
bgrole: "캐릭터 배경",
gring: "생성 중...",
uprolefirst: "먼저 캐릭터 이미지를 업로드하세요",
uprolefail: "업로드 실패",
upvideo: "+ 템플릿 댄스 비디오 업로드",
usevideo: "+ 공식 템플릿 사용",
moban: "댄스 템플릿",
moban2: "템플릿 이름",
use: "사용"
}

}
Loading

0 comments on commit f59e27f

Please sign in to comment.