這篇文章主要介紹了利用Python3怎么將視頻轉(zhuǎn)換成字符動(dòng)畫(huà),此處通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考價(jià)值,需要的朋友可以參考下:
目前創(chuàng)新互聯(lián)已為數(shù)千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管維護(hù)、企業(yè)網(wǎng)站設(shè)計(jì)、瀘縣網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。Python是一種跨平臺(tái)的、具有解釋性、編譯性、互動(dòng)性和面向?qū)ο蟮哪_本語(yǔ)言,其最初的設(shè)計(jì)是用于編寫(xiě)自動(dòng)化腳本,隨著版本的不斷更新和新功能的添加,常用于用于開(kāi)發(fā)獨(dú)立的項(xiàng)目和大型項(xiàng)目。
具體代碼如下所示:
# -*- coding:utf-8 -*- import json import os import subprocess from pathlib import Path from cv2 import cv2 import numpy as np from time import time import webbrowser play_chars_js = ''' let i = 0; window.setInterval(function(){ let img = frames[i++]; let html = "" for(let line of img){ for(let char of line){ let [[r,g,b], ch] = char; html += '<span >'+ ch + '</span>' // html += '<span >'+ ch + '</span>' } html += "<br>" } document.getElementsByClassName("video-panel")[0].innerHTML = html }, 1000/fps); document.getElementsByTagName("audio")[0].play(); ''' class VideoToHtml: # 像素形狀,因?yàn)轭伾呀?jīng)用rgb控制了,這里的pixels其實(shí)可以隨意排 pixels = "$#@&%ZYXWVUTSRQPONMLKJIHGFEDCBA098765432?][}{/)(><zyxwvutsrqponmlkjihgfedcba*+1-." def __init__(self, video_path, fps_for_html=8, time_interval=None): """ :param video_path: 字符串, 視頻文件的路徑 :param fps_for_html: 生成的html的幀率 :param time_interval: 用于截取視頻(開(kāi)始時(shí)間,結(jié)束時(shí)間)單位秒 """ self.video_path = Path(video_path) # 從指定文件創(chuàng)建一個(gè)VideoCapture對(duì)象 self.cap = cv2.VideoCapture(video_path) self.width = self.cap.get(cv2.CAP_PROP_FRAME_WIDTH) self.height = self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT) self.frames_count_all = self.cap.get(cv2.CAP_PROP_FRAME_COUNT) self.fps = self.cap.get(cv2.CAP_PROP_FPS) self.resize_width = None self.resize_height = None self.frames_count = 0 self.fps_for_html = fps_for_html self.time_interval = time_interval def video2mp3(self): """#調(diào)用ffmpeg獲取mp3音頻文件""" mp3_path = self.video_path.with_suffix('.mp3') subprocess.call('ffmpeg -i ' + str(self.video_path) + ' -f mp3 ' + str(mp3_path), shell=True) return mp3_path def set_width(self, width): """只能縮小,而且始終保持長(zhǎng)寬比""" if width >= self.width: return False else: self.resize_width = width self.resize_height = int(self.height * (width / self.width)) return True def set_height(self, height): """只能縮小,而且始終保持長(zhǎng)寬比""" if height >= self.height: return False else: self.resize_height = height self.resize_width = int(self.width * (height / self.height)) return True def resize(self, img): """ 將img轉(zhuǎn)換成需要的大小 原則:只縮小,不放大。 """ # 沒(méi)指定就不需resize了 if not self.resize_width or not self.resize_height: return img else: size = (self.resize_width, self.resize_height) return cv2.resize(img, size, interpolation=cv2.INTER_CUBIC) def get_img_by_pos(self, pos): """獲取到指定位置的幀""" # 把指針移動(dòng)到指定幀的位置 self.cap.set(cv2.CAP_PROP_POS_FRAMES, pos) # cap.read() 返回值介紹: # ret 布爾值,表示是否讀取到圖像 # frame 為圖像矩陣,類型為 numpy.ndarray. ret, frame = self.cap.read() return ret, frame def get_frame_pos(self): """生成需要獲取的幀的位置,使用了惰性求值""" step = self.fps / self.fps_for_html # 如果未指定 if not self.time_interval: self.frames_count = int(self.frames_count_all / step) # 更新count return (int(step * i) for i in range(self.frames_count)) # 如果指定了 start, end = self.time_interval pos_start = int(self.fps * start) pos_end = int(self.fps * end) self.frames_count = int((pos_end - pos_start) / step) # 更新count return (pos_start + int(step * i) for i in range(self.frames_count)) def get_imgs(self): assert self.cap.isOpened() for i in self.get_frame_pos(): ret, frame = self.get_img_by_pos(i) if not ret: print("讀取失敗,跳出循環(huán)") break yield self.resize(frame) # 惰性求值 # 結(jié)束時(shí)要釋放空間 self.cap.release() def get_char(self, gray): percent = gray / 255 # 轉(zhuǎn)換到 0-1 之間 index = int(percent * (len(self.pixels) - 1)) # 拿到index return self.pixels[index] def get_json_pic(self, img): """測(cè)試階段,不實(shí)用""" json_pic = [] # 寬高剛好和size相反,要注意。(這是numpy的特性。。) height, width, channel = img.shape # 轉(zhuǎn)換成灰度圖,用來(lái)選擇合適的字符 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) for y in range(height): line = [] for x in range(width): r, g, b = img[y][x] gray = img_gray[y][x] char = self.get_char(gray) line.append([[int(r), int(g), int(b)], char]) json_pic.append(line) return json.dumps(json_pic) def write_html_with_json(self, file_name): """測(cè)試階段,不實(shí)用""" mp3_path = self.video2mp3() time_start = time() with open(file_name, 'w') as html: # 要記得設(shè)置monospace等寬字體,不然沒(méi)法玩 html.write('<!DOCTYPE html>' '<html>' '<body >' '<div class="video-panel"></div>' f'<audio src="{mp3_path.name}" autoplay controls></audio>' '</body>' '<script>' 'var frames=[\n') try: i = 0 for img in self.get_imgs(): json_pic = self.get_json_pic(img) html.write(f"{json_pic},") if i % 20: print(f"進(jìn)度:{i/self.frames_count * 100:.2f}%, 已用時(shí):{time() - time_start:.2f}") i += 1 finally: html.write('\n];\n' f'let fps={self.fps_for_html};\n' f'{play_chars_js}' '</script>\n' '</html>') def main(): # 視頻路徑,換成你自己的 video_path = "ceshi.mp4" video2html = VideoToHtml(video_path, fps_for_html=8) video2html.set_width(120) html_name = Path(video_path).with_suffix(".html").name video2html.write_html_with_json(html_name) if __name__ == "__main__": main()
到此這篇關(guān)于利用Python3怎么將視頻轉(zhuǎn)換成字符動(dòng)畫(huà)的文章就介紹到這了,更多相關(guān)利用Python3怎么將視頻轉(zhuǎn)換成字符動(dòng)畫(huà)的內(nèi)容請(qǐng)搜索創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
當(dāng)前名稱:利用Python3怎么將視頻轉(zhuǎn)換成字符動(dòng)畫(huà)-創(chuàng)新互聯(lián)
鏈接URL:http://jinyejixie.com/article6/csdcog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、網(wǎng)站改版、網(wǎng)站營(yíng)銷、網(wǎng)站內(nèi)鏈、電子商務(wù)、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容