最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Python實現視頻拼接效果

 更新時間:2025年02月07日 16:10:56   作者:AI算法網奇  
這篇文章主要為大家詳細介紹了使用Python實現視頻拼接效果的兩種方法,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

方法一:

視頻較長,分辨率較大,這個效果很好,不耗用內存 ffmpeg

 import subprocess
import glob
import os
from natsort import natsorted
base_dir = r'C:\Users\Administrator\Videos\shuiyin\result'
output_file = r'output_shuiyin.mp4'
video_paths = glob.glob(base_dir + '/*.mp4')
video_paths = natsorted(video_paths)
with open('file_list.txt', 'w') as f:
    for file in video_paths:
        f.write(f"file '{file}'\n")
ffmpeg_command = [
    'ffmpeg',
    '-f', 'concat',           # 指定拼接模式
    '-safe', '0',             # 允許絕對路徑
    '-i', 'file_list.txt',    # 輸入的文件列表
    '-c:v', 'libx264',        # 使用 libx264 編碼器
    '-c:a', 'aac',            # 使用 aac 編碼音頻
    '-strict', 'experimental',# 使用實驗性編碼
    output_file               # 輸出文件路徑
]
subprocess.run(ffmpeg_command, check=True)
 
print(f"視頻拼接完成,輸出文件:{output_file}")

方法二:

利用imageio,適合視頻較短

import glob
from natsort import natsorted
from moviepy.editor import VideoFileClip, concatenate_videoclips
import glob
import os.path
 
from natsort import natsorted
import cv2
import imageio
 
if __name__ == '__main__':
    #內存
    base_dir =r"C:\Users\Administrator\Videos\shuiyin\0127"
    base_dir =r'C:\Users\Administrator\Videos\shuiyin\result'
    output_path = "pinjie_shuiyin.mp4"
    video_paths =glob.glob(base_dir +'/*.mp4')
    video_paths=natsorted(video_paths)
    imgs=[]
    res = []
    for file in video_paths:
        cap_a = cv2.VideoCapture(file)  # 打開視頻B
        fps = cap_a.get(cv2.CAP_PROP_FPS)
        frame_count = 0
        print(file)
        while True:
            ret, frame_a = cap_a.read()
            if not ret:
                break  # 如果沒有讀取到幀,則跳出循環(huán)
            res.append(cv2.cvtColor(frame_a, cv2.COLOR_BGR2RGB))
            frame_count += 1  # 釋放視頻資源
        cap_a.release()
    imageio.mimsave(output_path, res, "mp4", fps=fps, macro_block_size=None)
 

方法三:

使用FFmpeg進行視頻拼接,主要以兩個文件為例進行合并,并且只轉換其中的視頻流

vector<string> fileList = { url_origin,url_add };//這是兩個文件
//獲得原始輸入視頻文件編碼等信息
const AVOutputFormat* ofmt = NULL;//輸出格式
AVFormatContext* ifmt_ctx = NULL, * ofmt_ctx = NULL;//視頻數據維護對象
AVPacket* pkt = NULL;//數據包

int ret;//函數執(zhí)行返回碼
int stream_index;//數據流索引

pkt = av_packet_alloc();//初始化數據包結構
if (!pkt)
{
	return;
}

if ((ret = avformat_open_input(&ifmt_ctx, url_origin, 0, 0) < 0))
{
	goto end;//打開文件失敗
}

//獲得輸出文件名
string out_file;
auto name = ifmt_ctx->iformat->name;//自動識別文件的封裝類型
//hevc只能使用MP4或者hevc封裝才能完成轉換,其余封裝報錯,因為這里進行了自動識別可以不用管具體格式
out_file.replace(out_file.find('.')+1, 3, name);
const char* out_filename = out_file.c_str();

//根據第一個文件獲得其中的編碼等參數,這里要求兩個文件的編碼格式一樣就是因為在寫入文件時用的是相同的配置沒有進行轉碼等操作
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0)
{
	goto end;
}

avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
if (!ofmt_ctx)
{
	goto end;
}

ofmt = ofmt_ctx->oformat;
//查找視頻流并復制視頻流的參數到輸出流
for (int i = 0; i < ifmt_ctx->nb_streams; ++i)
{
	AVStream* in_stream = ifmt_ctx->streams[i];
	AVCodecParameters* in_codecpar = in_stream->codecpar;
	if (in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO)//非視頻流跳過
	{
		continue;
	}
	AVStream* out_stream = avformat_new_stream(ofmt_ctx, NULL);//創(chuàng)建輸出流
	if (!out_stream)
	{
		goto end;
	}
	ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);//復制解碼器參數
	if (ret < 0)
	{
		goto end;
	}
	out_stream->time_base = in_stream->time_base;//復制時間基
	stream_index = i;
	out_stream->codecpar->codec_tag = 0;
	break;
}
avformat_close_input(&ifmt_ctx);//關閉文件

//打開輸出文件
if (!(ofmt->flags & AVFMT_NOFILE))
{
	ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
	if (ret < 0)
	{
		goto end;
	}
}

ret = avformat_write_header(ofmt_ctx, NULL);//寫入頭信息,如編碼等內容
if (ret < 0)
{
	goto end;
}

int64_t i = 0;//用于計算時間戳,同時也是幀數
int64_t p_max_dts = 0;//用于拼文件的時間戳

for (int index = 0; index < fileList.size(); ++index)//遍歷文件
{
	if ((ret = avformat_open_input(&ifmt_ctx, fileList[index].c_str(), 0, 0)) < 0)
	{
		goto end;
	}

	if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0)//查找文件流信息
	{
		goto end;
	}

	//對流直接進行轉寫
	while (1)
	{
		AVStream* in_stream, * out_stream;
		ret = av_read_frame(ifmt_ctx, pkt);
		if (ret < 0)
		{
			break;
		}
		pkt->stream_index = stream_index;//視頻流編號
		//這里做一個提示,因為上述的例子只有視頻沒有音頻所以不會越界,如果存在多種流的這里需要看一下你new了幾個流,是否會越界
		in_stream = ifmt_ctx->streams[stream_index];
		out_stream = ofmt_ctx->streams[stream_index];

		//這里要對時間戳進行處理,否則寫入的時候會失敗
		//單幀時長
		int64_t frameDuration = av_rescale_q(1, av_inv_q(in_stream->time_base), in_stream->r_frame_rate);
		//將單幀的時間從輸入流轉化到輸出流時間
		int64_t _t = av_rescale_q(frameDuration, in_stream->time_base, out_stream->time_base);

		//計算時間戳,并進行累計以推算后面的時間戳
		p_max_dts = _t * (i);
		pkt->dts = p_max_dts;
		pkt->pts = pkt->dts;
		
		//如果音視頻都需要寫入可能需要這個函數:av_interleaved_write_frame,他會進行交叉寫入
		//pkt現在是空的,這個函數會獲得pkt內容的所有權并重置,因此不需要unref,但是write_frame情況不同,需要手動釋放
		ret = av_write_frame(ofmt_ctx, pkt);//直接將包寫入輸出文件不進行解碼
		av_packet_unref(pkt);
		if (ret < 0)
		{
			break;
		}
		++i;
	}

	//關閉文件
	avformat_close_input(&ifmt_ctx);
}

av_write_trailer(ofmt_ctx);//寫文件尾

end:
	av_packet_free(&pkt);//這里傳指針,因為要將pkt設為null
	avformat_close_input(&ifmt_ctx);//同理
	if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
	{
		avio_closep(&ofmt_ctx->pb);//avio打開要釋放
	}
	avformat_free_context(ofmt_ctx);
	if (ret < 0 && ret != AVERROR_EOF)
	{
		return;//異常結束
	}

這個示例可以完成視頻流的復制拼接,是一個比較簡單的示例,要求文件編碼等信息必須一致,不進行轉碼,速度比較快。

到此這篇關于使用Python實現視頻拼接效果的文章就介紹到這了,更多相關Python視頻拼接內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python一行代碼實現快速排序的方法

    Python一行代碼實現快速排序的方法

    排序算法是在高考或中考中出現頻率最多的點,所以大家要掌握,今天小編給大家?guī)砹送ㄟ^Python一行代碼實現快速排序的方法,感興趣的朋友跟隨小編一起看看吧
    2019-04-04
  • Python實現類繼承實例

    Python實現類繼承實例

    這篇文章主要介紹了Python實現類繼承實例,需要的朋友可以參考下
    2014-07-07
  • Pandas中把dataframe轉成array的方法

    Pandas中把dataframe轉成array的方法

    下面小編就為大家分享一篇Pandas中把dataframe轉成array的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • python抓取網頁中的圖片示例

    python抓取網頁中的圖片示例

    這篇文章主要介紹了python抓取網頁中圖片的示例,需要的朋友可以參考下
    2014-02-02
  • Python標準庫中內置裝飾器@staticmethod和@classmethod

    Python標準庫中內置裝飾器@staticmethod和@classmethod

    裝飾器是Python中強大而靈活的功能,用于修改或增強函數或方法的行為,本文就來介紹一下Python標準庫中內置裝飾器@staticmethod和@classmethod,感興趣的可以了解一下
    2023-10-10
  • 詳解python-圖像處理(映射變換)

    詳解python-圖像處理(映射變換)

    這篇文章主要介紹了python-圖像處理(映射變換),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • 利用python繪制蜂群圖的示例代碼

    利用python繪制蜂群圖的示例代碼

    蜂群圖可以不重疊的顯示各數據點的分布,相對于散點圖,所繪制的點彼此靠近且不會重疊,能有效呈現出點分布的局部密度信息,本文給大家介紹了如何利用python繪制蜂群圖,文中有詳細的代碼示例供大家參考,需要的朋友可以參考下
    2024-03-03
  • 在python中只選取列表中某一縱列的方法

    在python中只選取列表中某一縱列的方法

    今天小編就為大家分享一篇在python中只選取列表中某一縱列的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-11-11
  • Python attrs提高面向對象編程效率詳細

    Python attrs提高面向對象編程效率詳細

    Python是面向對象的語言,一般情況下使用面向對象編程會使得開發(fā)效率更高,軟件質量更好,并且代碼更易于擴展,可讀性和可維護性也更高,但是Python的類寫起來是真的累,這是可以在創(chuàng)建類的時候自動添加上attrs模塊,下面文章我們就來介紹這個東西,需要的朋友可參考一下
    2021-09-09
  • 利用python爬取斗魚app中照片方法實例

    利用python爬取斗魚app中照片方法實例

    最近在學習python,通過實踐是學習的一個好辦法,下面這篇文章就來給大家介紹了關于利用python爬取斗魚app中照片的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友下面來一起看看吧。
    2017-12-12

最新評論

鲜城| 衢州市| 澳门| 潼南县| 宁河县| 通榆县| 康平县| 辽中县| 旅游| 尼玛县| 镇原县| 南江县| 监利县| 郎溪县| 巴里| 舟山市| 民和| 贺兰县| 太康县| 诸暨市| 黄大仙区| 屯昌县| 峡江县| 星子县| 河津市| 兴宁市| 夏津县| 新河县| 甘孜县| 商丘市| 安康市| 鄂州市| 基隆市| 涡阳县| 衡阳县| 拉孜县| 沙坪坝区| 临泉县| 临夏市| 营口市| 吉安县|