add wav2lip customvideo
parent
0c63e9a11b
commit
391512f68c
@ -0,0 +1,81 @@
|
||||
import math
|
||||
import torch
|
||||
import numpy as np
|
||||
|
||||
import os
|
||||
import time
|
||||
import cv2
|
||||
import glob
|
||||
import pickle
|
||||
import copy
|
||||
|
||||
import queue
|
||||
from queue import Queue
|
||||
from threading import Thread, Event
|
||||
from io import BytesIO
|
||||
import soundfile as sf
|
||||
|
||||
from tqdm import tqdm
|
||||
def read_imgs(img_list):
|
||||
frames = []
|
||||
print('reading images...')
|
||||
for img_path in tqdm(img_list):
|
||||
frame = cv2.imread(img_path)
|
||||
frames.append(frame)
|
||||
return frames
|
||||
|
||||
class BaseReal:
|
||||
def __init__(self, opt):
|
||||
self.opt = opt
|
||||
self.sample_rate = 16000
|
||||
self.chunk = self.sample_rate // opt.fps # 320 samples per chunk (20ms * 16000 / 1000)
|
||||
|
||||
self.curr_state=0
|
||||
self.custom_img_cycle = {}
|
||||
self.custom_audio_cycle = {}
|
||||
self.custom_audio_index = {}
|
||||
self.custom_index = {}
|
||||
self.custom_opt = {}
|
||||
self.__loadcustom()
|
||||
|
||||
def __loadcustom(self):
|
||||
for item in self.opt.customopt:
|
||||
print(item)
|
||||
input_img_list = glob.glob(os.path.join(item['imgpath'], '*.[jpJP][pnPN]*[gG]'))
|
||||
input_img_list = sorted(input_img_list, key=lambda x: int(os.path.splitext(os.path.basename(x))[0]))
|
||||
self.custom_img_cycle[item['audiotype']] = read_imgs(input_img_list)
|
||||
self.custom_audio_cycle[item['audiotype']], sample_rate = sf.read(item['audiopath'], dtype='float32')
|
||||
self.custom_audio_index[item['audiotype']] = 0
|
||||
self.custom_index[item['audiotype']] = 0
|
||||
self.custom_opt[item['audiotype']] = item
|
||||
|
||||
def mirror_index(self,size, index):
|
||||
#size = len(self.coord_list_cycle)
|
||||
turn = index // size
|
||||
res = index % size
|
||||
if turn % 2 == 0:
|
||||
return res
|
||||
else:
|
||||
return size - res - 1
|
||||
|
||||
def get_audio_stream(self,audiotype):
|
||||
idx = self.custom_audio_index[audiotype]
|
||||
stream = self.custom_audio_cycle[audiotype][idx:idx+self.chunk]
|
||||
self.custom_audio_index[audiotype] += self.chunk
|
||||
if self.custom_audio_index[audiotype]>=stream.shape[0]:
|
||||
self.curr_state = 1 #当前视频不循环播放,切换到静音状态
|
||||
return stream
|
||||
|
||||
def set_curr_state(self,audiotype, reinit):
|
||||
self.curr_state = audiotype
|
||||
if reinit:
|
||||
self.custom_audio_index[audiotype] = 0
|
||||
self.custom_index[audiotype] = 0
|
||||
|
||||
# def process_custom(self,audiotype:int,idx:int):
|
||||
# if self.curr_state!=audiotype: #从推理切到口播
|
||||
# if idx in self.switch_pos: #在卡点位置可以切换
|
||||
# self.curr_state=audiotype
|
||||
# self.custom_index=0
|
||||
# else:
|
||||
# self.custom_index+=1
|
@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"audiotype":2,
|
||||
"imgpath":"data/customvideo/image",
|
||||
"audiopath":"data/customvideo/audio.wav"
|
||||
}
|
||||
]
|
@ -0,0 +1,113 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>WebRTC webcam</title>
|
||||
<style>
|
||||
button {
|
||||
padding: 8px 16px;
|
||||
}
|
||||
|
||||
video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.option {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
#media {
|
||||
max-width: 1280px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="option">
|
||||
<input id="use-stun" type="checkbox"/>
|
||||
<label for="use-stun">Use STUN server</label>
|
||||
</div>
|
||||
<button id="start" onclick="start()">Start</button>
|
||||
<button id="stop" style="display: none" onclick="stop()">Stop</button>
|
||||
<input type="hidden" id="sessionid" value="0">
|
||||
<form class="form-inline" id="echo-form">
|
||||
<div class="form-group">
|
||||
<p>input text</p>
|
||||
|
||||
<textarea cols="2" rows="3" style="width:600px;height:50px;" class="form-control" id="message">test</textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default">Send</button>
|
||||
</form>
|
||||
|
||||
<div id="media">
|
||||
<h2>Media</h2>
|
||||
|
||||
<audio id="audio" autoplay="true"></audio>
|
||||
<video id="video" style="width:600px;" autoplay="true" playsinline="true"></video>
|
||||
</div>
|
||||
<button id="custom" onclick="custom()">切换视频</button>
|
||||
<input type="text" id="audiotype" value="0">
|
||||
|
||||
<script src="client.js"></script>
|
||||
<script type="text/javascript" src="http://cdn.sockjs.org/sockjs-0.3.4.js"></script>
|
||||
<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.1.min.js"></script>
|
||||
</body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
|
||||
$(document).ready(function() {
|
||||
// var host = window.location.hostname
|
||||
// var ws = new WebSocket("ws://"+host+":8000/humanecho");
|
||||
// //document.getElementsByTagName("video")[0].setAttribute("src", aa["video"]);
|
||||
// ws.onopen = function() {
|
||||
// console.log('Connected');
|
||||
// };
|
||||
// ws.onmessage = function(e) {
|
||||
// console.log('Received: ' + e.data);
|
||||
// data = e
|
||||
// var vid = JSON.parse(data.data);
|
||||
// console.log(typeof(vid),vid)
|
||||
// //document.getElementsByTagName("video")[0].setAttribute("src", vid["video"]);
|
||||
|
||||
// };
|
||||
// ws.onclose = function(e) {
|
||||
// console.log('Closed');
|
||||
// };
|
||||
|
||||
$('#echo-form').on('submit', function(e) {
|
||||
e.preventDefault();
|
||||
var message = $('#message').val();
|
||||
console.log('Sending: ' + message);
|
||||
console.log('sessionid: ',document.getElementById('sessionid').value);
|
||||
fetch('/human', {
|
||||
body: JSON.stringify({
|
||||
text: message,
|
||||
type: 'echo',
|
||||
interrupt: true,
|
||||
sessionid:parseInt(document.getElementById('sessionid').value),
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
method: 'POST'
|
||||
});
|
||||
//ws.send(message);
|
||||
$('#message').val('');
|
||||
});
|
||||
|
||||
function custom() {
|
||||
fetch('/set_audiotype', {
|
||||
body: JSON.stringify({
|
||||
audiotype: parseInt(document.getElementById('audiotype').value),
|
||||
reinit: false,
|
||||
sessionid:parseInt(document.getElementById('sessionid').value),
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
method: 'POST'
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</html>
|
Loading…
Reference in New Issue