def save_mp4_from_vid_and_audio(self, video_tensor, audio_wav=None, fps=25, sr=16000, outname=None, extract_frames_hop=None): """ :param video_tensor: tchw :param sr: :return: """ from moviepy.audio.AudioClip import AudioArrayClip from moviepy.video.VideoClip import VideoClip video_tensor = video_tensor.transpose([0, 2, 3, 1]) # thwc # that's to avoid error due to float precision vid_dur = len(video_tensor) * (1. / fps) - 1e-6 v_clip = VideoClip(lambda t: video_tensor[int(np.round(t * 25))], duration=vid_dur) import tempfile if outname: outfile = os.path.join(self.savedir, outname) if not outfile.endswith('.mp4'): outfile += '.mp4' else: outfile = os.path.join(self.savedir, '%03d.mp4' % self.id) if audio_wav is not None: _, temp_audiofile = tempfile.mkstemp(dir='/dev/shm', suffix='.wav') import torch if isinstance(audio_wav, torch.Tensor): audio_wav = audio_wav.numpy() import scipy.io scipy.io.wavfile.write(temp_audiofile, 16000, audio_wav) self.id += 1 try: os.makedirs(os.path.dirname(outfile)) except: pass _, temp_videofile = tempfile.mkstemp(dir='/dev/shm', suffix='.mp4') v_clip.write_videofile(temp_videofile, fps=25, verbose=False) if audio_wav is not None: command = ("ffmpeg -threads 1 -loglevel error -y -i {} -i {} " "-c:v copy -map 0:v:0 -map 1:a:0 -pix_fmt yuv420p " "-shortest {}").format(temp_videofile, temp_audiofile, outfile) from subprocess import call cmd = command.split(' ') call(cmd) else: import shutil shutil.move(temp_videofile, outfile) v_clip.close() import imageio if extract_frames_hop: # extract the video as frames for paper frames_dir = os.path.join( os.path.dirname(outfile), 'frames_' + os.path.basename(outfile).replace('.mp4', '')) os.makedirs(frames_dir, exist_ok=True) import scipy.misc for fr_id, frame in enumerate(video_tensor[::extract_frames_hop]): scipy.misc.imsave(frames_dir + '/%04d.png' % fr_id, frame[:, :-5, :]) pass
if args.image_resize == 'fill' and args.crop_output: print(f"Cropping output video to {unfill_width}x{unfill_height}") output_clip = movie_crop(output_clip, x_center=256 // 2, y_center=256 // 2, width=unfill_width, height=unfill_height) print("Saving Video...") output_clip.write_videofile(output_video_path, logger=None, verbose=False, **codecs[args.codec]) print("Video saved to", output_video_path) print() if args.stack: print("Saving Side by Side Video") stack_clip = clips_array([[output_clip.margin(right=10), source_video]]) stack_path = output_video_path.rsplit('.', 1)[0] + '_stacked.mp4' stack_clip.write_videofile(stack_path, logger=None, verbose=False, **codecs[args.codec]) print("Stacked Video saved to", stack_path) stack_clip.close() output_clip.close() source_video.close()