Mac 截取一个视频中部分片段(命令行方法)

本文详细介绍如何在苹果电脑上使用Python脚本配合ffmpeg命令行工具,精准截取视频中的特定片段。通过创建并运行一个简单的Python脚本来计算时间差,并利用ffmpeg进行视频截取,实现高效且精确的视频编辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

苹果电脑中想要截取一个视频中的某一段视频,参考了百度经验

打开命令行,执行以下操作

mkdir bin
cd bin
touch capture.txt
open capture.txt

 

输入一下内容:

#! /usr/local/bin/python3
import os, sys
import datetime
file, start, end, target = sys.argv[1:]
h0, m0, s0 = [int(i) for i in start.split(":")]
h1, m1, s1 = [int(i) for i in end.split(":")]
t0 = datetime.datetime(2016, 1, 1, h0, m0, s0)
t1 = datetime.datetime(2016, 1, 1, h1, m1, s1)
delta = str(t1 - t0)
c = "ffmpeg -i {} -ss {} -t {} -acodec copy -vcodec copy {}"
os.system(c.format(file, start, delta, target))

保存文本 ,command + s

继续在命令行里执行以下命令

chmod 775 ~/bin/capture.txt

下面截取视频:

./capture.txt 你要截取的视频的路径 00:00:00 00:10:00 保存的截取后的视频的路径+文件名

 

<think>我们使用WORLD声码器来实现音频特征转换。主要步骤包括:1.提取视频A和视频B的音频。2.使用WORLD声码器对两个音频进行分解,得到基频(F0)、频谱包络(sp)和非周期序列(ap)。3.将视频A的频谱包络(sp_A)与视频B的基频(F0_B)和非周期序列(ap_B)结合,合成新的音频。4.将新音频替换到视频B中,保持视频B的画面和原有声音特征(这里指用视频A的频谱包络来改变音色,而保留视频B的基频和节奏,这样声音听起来还是视频B的说话者,但音色像视频A)。但是,注意:我们通常希望保持视频B的说话者特征(即音色),而将视频A的说话者特征转换到视频B上,所以实际上应该是将视频A的频谱包络(代表音色)与视频B的基频(代表音高变化)和非周期序列(代表噪声特性)结合。然而,这里用户要求的是将视频A的音频特征应用于视频B,并且保持视频B的声音不变?这有点矛盾。通常,变声是改变音色,而保持原内容(即基频和节奏等)不变。但用户说“保持原视频B声音不变”,可能是指视频B的画面和音频内容(说的话)不变,但音色改变为视频A的音色。因此,我们这样理解:将视频B的说话内容(音频)用视频A的音色来重新合成,这样视频B的音频听起来就像是视频A的人在说视频B的内容。具体步骤:1.提取音频:使用ffmpeg从视频A和视频B中提取音频(WAV格式)。2.使用WORLD分解音频:-对视频A的音频:提取F0_A,sp_A,ap_A-对视频B的音频:提取F0_B,sp_B,ap_B3.合成新音频:使用视频A的频谱包络(sp_A)和视频B的基频(F0_B)以及视频B的非周期序列(ap_B)来合成新的音频。注意,这里我们使用视频B的基频和非周期序列,因为我们要保留视频B的语调、节奏和声音的噪声特性,而使用视频A的频谱包络(代表音色)来改变音色。4.将合成的新音频替换到视频B中,替换掉原来的音频。注意:由于基频F0是音高,频谱包络sp是音色,非周期序列ap是声音的噪声特性。因此,这样合成后,新音频的音色来自A,而说话的内容(基频变化,即语调)和噪声特性来自B。但请注意,基频F0也会影响音色,所以完全分离可能不理想,但这是常用的方法。实现步骤:第一步:安装必要的库-安装pyworld(WORLD声码器的Python封装)-安装ffmpeg(用于视频和音频的提取与合成)第二步:提取音频-使用ffmpeg提取视频A和视频B的音频为WAV文件。第三步:使用pyworld处理音频-读取WAV文件-使用pyworld提取特征(F0,sp,ap)-合成新音频:使用sp_A,F0_B,ap_B第四步:将合成的新音频合并到视频B中,替换原音频。具体代码实现:1.安装依赖:```pipinstallpyworldpipinstallnumpypipinstallsoundfile#用于读写音频文件```另外,需要安装ffmpeg,并确保ffmpeg在系统路径中。2.提取音频(使用ffmpeg命令行):```pythonimportsubprocessdefextract_audio(video_path,audio_output):subprocess.call(['ffmpeg','-i',video_path,'-vn','-acodec','pcm_s16le','-ar','44100','-ac','1',audio_output])```3.使用pyworld处理:```pythonimportnumpyasnpimportpyworldaspwimportsoundfileassfdefextract_features(audio_path):data,fs=sf.read(audio_path)#转换为float64data=data.astype(np.float64)#提取特征f0,time=pw.dio(data,fs)#基频提取f0=pw.stonemask(data,f0,time,fs)#改进基频sp=pw.cheaptrick(data,f0,time,fs)#频谱包络ap=pw.d4c(data,f0,time,fs)#非周期序列returnfs,f0,sp,apdefsynthesize(fs,f0,sp,ap):synthesized=pw.synthesize(f0,sp,ap,fs)returnsynthesized```4.特征转换与合成:```python#读取视频A的音频并提取特征fs_A,f0_A,sp_A,ap_A=extract_features('audio_A.wav')#读取视频B的音频并提取特征fs_B,f0_B,sp_B,ap_B=extract_features('audio_B.wav')#注意:两个音频的采样率必须相同,如果不相同,需要转换iffs_A!=fs_B:#这里我们假设用户提供的两个视频的音频采样率相同,如果不同需要转换#但为了简单,我们假设相同,否则需要重采样raiseValueError("采样率不同,需要重采样")#使用视频A的频谱包络(sp_A)和视频B的基频(f0_B)和非周期序列(ap_B)合成#但是,注意:sp_A和sp_B的帧数可能不同(因为音频时长不同),所以我们需要对sp_A进行时间对齐或者插值?#实际上,我们期望将视频A的频谱包络应用到整个视频B的音频上,但是视频A和视频B的音频时长可能不同。#一种简单做法:如果视频A的音频时长大于等于视频B,则截取sp_A的前面与视频B相同长度的部分;如果小于,则循环填充?但这样效果不好。#更好的做法:将视频A的sp_A进行时间拉伸,使其与视频B的时长一致。但时间拉伸本身是一个复杂的问题。这里我们假设两个音频长度相同(或者用户要求是相同长度?)#为了简化,我们假设用户处理的视频A和视频B的音频长度相同。否则,需要更复杂的处理(比如动态时间规整DTW)。#检查长度iflen(f0_B)!=sp_A.shape[0]:#如果sp_A的帧数(第一维)和f0_B的长度(帧数)不一致,我们需要调整sp_A#使用线性插值fromscipy.interpolateimportinterp1doriginal_frames=np.arange(sp_A.shape[0])target_frames=np.linspace(0,sp_A.shape[0]-1,len(f0_B))#对每个频率bin进行插值new_sp=np.zeros((len(f0_B),sp_A.shape[1]))foriinrange(sp_A.shape[1]):interp_func=interp1d(original_frames,sp_A[:,i],kind='linear')new_sp[:,i]=interp_func(target_frames)sp_A=new_sp#同样检查ap_B,但ap_B的维度和sp_A一样吗?在pyworld中,ap的维度和sp相同#所以,我们只需要调整sp_A,因为ap_B和f0_B的长度是一致的(都是通过视频B的音频分解得到的帧数)#合成音频synthesized_audio=synthesize(fs_B,f0_B,sp_A,ap_B)#保存合成的音频sf.write('synthesized_audio.wav',synthesized_audio,fs_B)```5.将合成的音频替换到视频B中:```pythondefreplace_audio(video_path,audio_path,output_path):subprocess.call(['ffmpeg','-i',video_path,'-i',audio_path,'-c:v','copy','-map','0:v:0','-map','1:a:0','-y',output_path])```注意:上述代码中,我们假设两个音频长度相同。如果不同,则需要对sp_A进行插值以匹配视频B音频的帧数(由f0_B的长度决定)。但这里插值只是简单的线性插值,可能不够完美。另外,WORLD声码器对基频的提取可能存在问题,例如在非浊音段(unvoiced)基频为0,而频谱包络和非周期序列在这些段仍然有效。上述处理应该可以保留这些特性。总结步骤:1.提取视频A和视频B的音频(WAV格式,单声道,相同采样率,如果不是则转换)。2.分别用pyworld提取特征。3.将视频A的频谱包络(sp_A)调整到与视频B的基频(f0_B)相同的帧数(通过插值)。4.用视频B的基频(f0_B)和视频B的非周期序列(ap_B)以及调整后的视频A的频谱包络(sp_A)合成新的音频。5.将新音频合并到视频B中,生成新的视频文件。注意:这种方法只能改变音色,而保留视频B的语调(基频)和内容。但是,由于频谱包络和基频的相互作用,效果可能并不完美,需要根据实际情况调整。另外,如果两个音频的采样率不同,需要在提取特征前重采样为相同采样率。同时,确保音频是单声道(如果不是,转换为单声道)。最后,给出完整的代码示例(假设两个视频的音频长度不同,则进行插值处理):</think>### 使用WORLD声码器实现音频特征转换的Python方案 我将指导你在Windows 10系统中使用Python和WORLD声码器实现视频A的音频特征转换到视频B的音频上,同时保持视频B的原始声音特性。以下是完整解决方案: #### 系统环境准备 1. 安装必要库: ```powershell pip install pyworld numpy soundfile ffmpeg-python moviepy ``` 2. 下载Windows版FFmpeg并添加到PATH: [FFmpeg官方下载](https://ffmpeg.org/download.html) #### 核心代码实现 ```python import ffmpeg import numpy as np import pyworld as pw import soundfile as sf from moviepy.editor import VideoFileClip def extract_audio_features(video_path): """提取音频特征(F0, sp, ap)""" # 提取音频 audio_path = 'temp.wav' ( ffmpeg.input(video_path) .output(audio_path, ar=48000, ac=1) .overwrite_output() .run() ) # 读取音频 data, fs = sf.read(audio_path) data = data.astype(np.float64) # WORLD特征提取 f0, timeaxis = pw.dio(data, fs) # 基频提取 f0 = pw.stonemask(data, f0, timeaxis, fs) # 基频优化 sp = pw.cheaptrick(data, f0, timeaxis, fs) # 频谱包络 ap = pw.d4c(data, f0, timeaxis, fs) # 非周期成分 return fs, f0, sp, ap def apply_audio_features(src_fs, src_sp, tgt_fs, tgt_f0, tgt_ap): """应用音频特征并合成新音频""" # 特征对齐处理 (关键步骤) if src_sp.shape[0] != tgt_f0.shape[0]: ratio = src_sp.shape[0] / tgt_f0.shape[0] new_sp = np.zeros((tgt_f0.shape[0], src_sp.shape[1])) for i in range(src_sp.shape[1]): new_sp[:, i] = np.interp( np.arange(tgt_f0.shape[0]), np.arange(src_sp.shape[0]) * ratio, src_sp[:, i] ) src_sp = new_sp # 合成新音频 (保留目标基频和非周期特征) synthesized = pw.synthesize(tgt_f0, src_sp, tgt_ap, tgt_fs) return synthesized def transfer_audio_features(video_a, video_b, output_path): """主函数:音频特征转换""" # 提取特征 fs_a, f0_a, sp_a, ap_a = extract_audio_features(video_a) fs_b, f0_b, sp_b, ap_b = extract_audio_features(video_b) # 应用特征并合成 new_audio = apply_audio_features(fs_a, sp_a, fs_b, f0_b, ap_b) # 保存新音频 sf.write('new_audio.wav', new_audio, int(fs_b)) # 替换视频B的音频 video_clip = VideoFileClip(video_b) audio_clip = AudioFileClip('new_audio.wav') video_clip.set_audio(audio_clip).write_videofile( output_path, codec='libx264', audio_codec='aac' ) # 使用示例 if __name__ == "__main__": transfer_audio_features( "video_a.mp4", "video_b.mp4", "output_video.mp4" ) ``` #### 关键处理说明 1. **特征对齐处理**: - 使用线性插值对齐频谱包络:`np.interp()` - 保持目标视频的基频($F0_B$)和非周期特征($ap_B$) - 仅替换频谱包络($sp_A \rightarrow sp_B$) 2. **WORLD声码器优势**: - **高质量输出**:优于传统声码器,保持自然语音听感[^1] - **高效处理**:无需逐样本点处理,48kHz采样率下仍高效[^3] - **开源免费**:无专利限制,可直接商用[^1] 3. **音频特征保留**: - 保留视频B的$F0$特征(基频/音调) - 保留视频B的$ap$特征(发声方式) - 仅替换$sp$特征(音色/音质) #### 注意事项 1. **采样率处理**: - 强制统一为48kHz采样率 - 单声道处理确保特征一致性 2. **视频格式兼容**: - 使用H.264/AAC编码保证兼容性 - 通过`moviepy`处理视频容器封装 3. **内存优化**: - 大视频文件建议分帧处理 - 可添加`pydub`进行流式处理 #### 效果说明 最终输出视频将: - 保持视频B的原始画面和内容 - 音频具有视频A的音色特征 - 保留视频B的语调节奏和发音特点 - 实现"视频B内容+视频A音色"的变声效果 > **提示**:对于更高质量的需求,可结合Tacotron模型进行端到端语音合成[^2],但需要额外训练数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值