IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【脚本资源】巧用 FFMEPG 为Android Studio制作提示音,用音乐舒缓压力 -> 正文阅读

[移动开发]【脚本资源】巧用 FFMEPG 为Android Studio制作提示音,用音乐舒缓压力

原理1 : -f wav -vn 作为编码参数,可转换音频
原理2: -af “afade=t=out:st=5:d=5” 作为滤镜参数,可淡出音频
原理3: gradle 调用 powershell 播放wave文件

afterEvaluate {
    gradle.buildFinished{ BuildResult buildResult ->
        if (buildResult.failure) {
            ['powershell', """(New-Object Media.SoundPlayer "D:\\Downloads\\music\\muse_SchivoNo.2.wav").PlaySync();"""].execute()
            println("failed doing task")
        } else {
            ['powershell', """(New-Object Media.SoundPlayer "D:\\Downloads\\music\\muse_SchivoNo.2.wav").PlaySync();"""].execute()
            println("build finished")
        }
    }
}

原理4: -af “reverse” 作为滤镜参数,可反转音频(倒放)
原理5: ffmpeg 滤镜可组合使用

脚本使用:

:wav 回车
:ao 回车
输入输出路径 回车 (默认使用源路径)
将源文件拖拽至此 回车 回车

即可生成淡出音频的BGM!

进阶 ——

:ar 回车 反转音频
:vr 回车 反转视频

:ao 指令 可以指定淡出时间,默认两秒:

如 :ao5 回车 则淡出最后五秒。

配合potplayer书签:

可配合potplayer书签功能截取视频片段(一对书签截取一段视频)。需设置potplayer保存设置到ini文件并在脚本中填写ini文件路径。如果没有,则转换整个文件。

资源

#!/usr/bin/env python
# -*-coding=utf-8 -*-
from datetime import *
import os
import re
import sys
import codecs
#reload(sys)
#sys.setdefaultencoding("ascii")
os.system('title 切割视频 - 脚本工具箱')a

def main():
	theta = 0;
	flibf = r"D:\software\PotPlayer\PotPlayerMini64.ini"
	#ffmpegexe = r'D:\Downloads\ffmpeg-4.1.3-win64-shared\bin\ffmpeg.exe'
	ffmpegexe = r"D:\software\ffmpeg\ffmpeg-n4.4-latest-win64-gpl-shared-4.4\bin\ffmpeg.exe"
	#ffmpegexe = r'ffmpeg.exe'
	#ffmpegexe = r'D:\Downloads\ffmpeg-4.2-win64-static\bin\ffmpeg.exe'

	global videoPathName
	global OutputPath
	lastVideoQuality=-1
	lastAccuracy=False
	global wave
	global fadeoutMusic
	global reverseVideo
	global reverseAudio
	fadeoutMusic = -1
	wave = False
	reverseVideo = False
	reverseAudio = False
	
	def receiveFunc():
		global videoPathName
		videoPathName = str(input("videoPathName")).replace('"', '')
		return videoPathName!="";
		
	def buildOutputPath(e):
		nopath=False
		if len(e)==0 or len(e)!=1 and not os.sep in e:
			nopath=True
		else:
			if len(e)==1:
				e = e+":\\harvest"
			try:
				if not os.path.exists(e):
					os.makedirs(e)
				if not os.path.exists(e):
					nopath=True
			except:
				nopath=True
		if nopath:
			e=None
			print("提示:路径设空")
		elif e[-1]!=os.sep:
			e=e+os.sep
			print("提示:路径设为::"+e)
		return e
	
	OutputPath="F:\\harvest\\"
	OutputPath=""
	PrevSpecName = None
	
	while True:
		videoPathNames = []
		Accuracy = []
		OutputPaths = []
		lastVideoQualitys = []
		
		while(receiveFunc()):
			isTmp = False
			if videoPathName.startswith("=="):
				if len(videoPathName) > 2:
					PrevSpecName = videoPathName
				else:
					videoPathName = PrevSpecName
				videoPathName = "C:\\tmp\\tmp.mp4"+videoPathName+"-";
				isTmp = True
			if videoPathName[0]==':':
				if False:
					print (0)
				elif videoPathName.startswith(':wav'):
					wave = videoPathName==':wav'
					print("波形音频!" if wave else "不波形音频!")
				elif videoPathName.startswith(':ao'):
					fadeoutMusic=videoPathName[3:]
					if len(fadeoutMusic)==0:
						fadeoutMusic = 2
					elif fadeoutMusic.isnumeric():
						fadeoutMusic = int(fadeoutMusic)
					else:
						fadeoutMusic = -1
					print(fadeoutMusic, "淡出音频!" if fadeoutMusic>=0 else "不淡出音频!")
				elif videoPathName.startswith(':ar'):
					reverseAudio = videoPathName==':ar'
					print("反转音频!" if reverseAudio else "不反转音频!")
				elif videoPathName.startswith(':vr'):
					reverseVideo = videoPathName==':vr'
					print("反转视频!" if reverseVideo else "不反转视频!")
				elif len(videoPathName)>1:
					if videoPathName.startswith(':t'):
						lastAccuracy='ts'
					else:
						videoPathName=videoPathName[1:]
						if videoPathName.isnumeric():
							lastAccuracy=True
							lastVideoQuality=int(videoPathName)
						else:
							OutputPath=buildOutputPath(videoPathName)
				else:
					lastAccuracy=True
			else:
				lastAccuracy_=lastAccuracy
				lastVideoQuality_=lastVideoQuality
				match=re.match('(.*)(:[0-9]?)$', videoPathName)
				if match!=None:
					videoPathName=match.group(1)
					args=match.group(2)
					lastAccuracy_=True
					if len(args)>1 and args[1:].isnumeric():
						lastVideoQuality_=int(args[1:])
				print(videoPathName)
				path_test = videoPathName;
				if path_test.endswith("-") and path_test.find("==")>0:
					path_test = path_test[:path_test.find("==")]
				if not os.path.isfile(path_test) and videoPathName!='x' and not videoPathName.endswith(".flv") and not videoPathName.endswith(".mp4"):
					OutputPath=buildOutputPath(path_test)
					continue
				videoPathNames.append(videoPathName)
				OutputPaths.append(OutputPath)
				Accuracy.append(lastAccuracy_)
				lastVideoQualitys.append(lastVideoQuality_)
		  
		f = codecs.open(flibf,"r","utf-16")
		flib = f.read()
		f.close()
		#获取文件名
		bmlOff = flib.find("[BMList]")
		bmlOff2 = flib.find("=\r",bmlOff)
		bml = flib[bmlOff:bmlOff2]
		#print bml
		o=bml.find(str(theta)+"=")
		findCount = 0
		while(bml.find("\n",o)!=-1):
			o=bml.find("\n",o)+2
			findCount+=1
		print ("acc = ",findCount,"\r\n") 
		for (index,videoPathI) in enumerate(videoPathNames):
			if videoPathI=='x':
				return;
			keyToFind = videoPathI
			hasSpecName = False
			if keyToFind.endswith("-") and keyToFind.find("==")>0:
				keyToFind = videoPathI[:videoPathI.find("==")]
				hasSpecName = True
			print("keyToFind is : ",keyToFind, hasSpecName, "\n")
			accurate_recode=Accuracy[index]
			for fileIdx in range(0,findCount):
				ducOff = bml.find(str(0+theta+fileIdx)+"=")
				ducOff2 = bml.find("\r",ducOff)
				try:
					videoPathName = bml[ducOff:ducOff2].split("=")[1]
				except IndexError:
					print ("\n\nError_log_ theta threshold is too big \n\n")
				#print ("acc = ",videoPathI,videoPathName)
				if(videoPathName!=keyToFind and keyToFind!='"'+videoPathName+'"'):
					continue
				o = 0
				while(videoPathName.find("\\",o)!=-1):
					o=videoPathName.find("\\",o)+1
				videoName = videoPathName[o:]
					
				if(hasSpecName):
					videoName = videoPathI[videoPathI.find("==")+2:-1]+".mp4"
					
				videoPath = videoPathName[:o]
				if OutputPaths[index]!=None and len(OutputPaths[index])>0:
					videoPath=OutputPaths[index]
				print("videoName is : ",videoName,videoPath, hasSpecName, "\n")
				#获取当前文件的书签列表
				#print flib.find("[BMItem_"+str(theta+fileIdx))
				itemSectionOff = flib.find("[BMItem_"+str(theta+fileIdx))
				#print flib.find("=\r",itemSectionOff)
				itemSectionOff2 = flib.find("=\r",itemSectionOff)
				section = flib[itemSectionOff:itemSectionOff2]

				bookMarkList = []
				for i in section.split("\r\n"):
					tmp = i.split("*")[0]
					if tmp.find("=")!=-1:
						bookMarkList.append(int(tmp.split("=")[1]))
				#print bookMarkList
				#获取当前文件的书签列表END

				cc = 0
				for i in range(int(len(bookMarkList)/2)):
					#print "doin"
					start = bookMarkList[i*2]
					end = bookMarkList[i*2+1]
					tm = start/1000
					h=int(tm/60/60)
					m=int(tm%(60*60)/60)
					s=int(tm%(60*60)%60)
					#print(start)
					tm1 = str(time(h,m,s))   +"."+str(start%1000)
					
					tm = end/1000
					h=int(tm/60/60)
					m=int(tm%(60*60)/60)
					s=int(tm%(60*60)%60)
					tm2 = str(time(h,m,s))   +"."+str(end%1000)
					
					
					codec=" -codec copy -avoid_negative_ts 1 -strict -2 "
					accurate = False
					if accurate_recode=='ts':
						codec=" -codec copy -copyts -avoid_negative_ts 1 -strict -2 -bsf:v h264_mp4toannexb -f mpegts "
					elif accurate_recode:
						accurate = True
						codec=" -codec copy  -c:v libx264 -avoid_negative_ts 1 -strict -2 "
						if lastVideoQualitys[index]>=0:
							codec+="-crf "+str(lastVideoQualitys[index])+" "
						
					suffix =  ".mp4"
					suffixIdx =  videoName.rfind(".")
					if suffixIdx > 0:
						suffix = videoName[suffixIdx:]
						videoName = videoName[:suffixIdx]
					if suffix==".flv":
						suffix = ".mp4"
					
					decode = codec
					if wave:
						suffix = ".wav"
						decode = " -f wav -vn "
						
					if reverseVideo:
						decode += " -vf \"reverse\" "
					if reverseAudio:
						decode += " -af \"areverse\" "
					
					new_path = videoPath+videoName+"_SchivoNo."+str(cc)+suffix
					while os.path.exists(new_path):
						cc+=1;
						new_path = videoPath+videoName+"_SchivoNo."+str(cc)+suffix
					cc+=1
					new_path='"'+new_path+'"'
					inputfile=" -accurate_seek "+"-i "+'"'+videoPathName+'"'
					duration = 1.0*(end-start)/1000
					sst=r' -ss '+ (tm1)+"  -t  "+str(duration)
					
					if fadeoutMusic>=0:
						# ' -af "afade=t=out:st=5:d=5" '
						d = fadeoutMusic
						st = duration-d
						if st < 0 :
							d/=2
							st = duration-d
						decode = f' -af "afade=t=out:st={st}:d={d}" '  + decode
					
					offset_and_input=sst+inputfile
					if accurate:
						offset_and_input=inputfile+sst
						
					#codec=" -codec copy -avoid_negative_ts 1 -strict -2 "
					#offset_and_input=inputfile+sst
						
					mingling=offset_and_input+decode+new_path
					print ("\r\ncommand on queue: FFMPEG "+mingling+"\n")
					mingling = ffmpegexe + mingling
					
					os.system(mingling+" -n")
				break
				
		#os.system("pause")

if __name__ == '__main__':
	main()
	os._exit(0)  
	

示例

将偶然看到的“美篇”BGM拿来,截取前两秒项目构建成功的提示音,是一种开放的感觉,open feeling,心胸开阔,开启无限可能。反转后作为构建失败的提示音,别有旋律,是一种幽然的警报声,紧张中带有诙谐感,开始无限调试。

用 FFMEPG 为Android Studio制作的提示音

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-12-25 11:21:31  更:2022-12-25 11:23:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:02:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码