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