搜索 社区服务 统计排行 帮助
  • 26658阅读
  • 24回复

[原创]RM、RMVB、AVI、MKV影音不同步解套(非重製式方法)

楼层直达
级别: 版主
注册时间:
2002-12-02
在线时间:
0小时
发帖:
3002
使用工具:AviSynth、real media splitter、ReClock、MPC
主要發生原因有兩大類:
[A]壓製時引發(Video及Audio索引鍵問題、I-Frame設置不良)
播放環境引發(PC之Video及Audio解碼時差、Codec安裝不良)

[A]方法除編輯重製外,還可用AviSynth做第二層轉換處理(應為時常把誤認為[A]所以建議用AviSynth)
這裡推薦 ReClock 這個 Filter

先介紹比較簡單的
解套方案
請安裝 ReClock-DSF 並執行 Configure ReClock
如圖游標(鼠標)處取消勾選(因為不希望ReClock-DSF永遠作用於任何播放器)


接著開啟 Media Player Classic
如圖加入濾鏡 ReClock Audio Renderer 並選取 偏好


現在用 Media Player Classic 開啟檔案看看是否改進了

ReClock-DSF 下載點
http://ogo.nerim.net/reclockfilter/main.htm

级别: 版主
注册时间:
2002-12-02
在线时间:
0小时
发帖:
3002
只看该作者 1楼 发表于: 2003-12-27
接者是介紹
[A]解套方案
用到了 avs 腳本,請先確認有安裝 AviSynth
這裡直接告知使用方法
1.先測得影音檔的 FPS 框架率為何?(如圖用右鍵->內容 或用 AVIcodec等工具得知)
右鍵->內容(Windows 檔案總管)

AVIcodec

2.開啟file_info.txt修改內容 -> 存檔
3.最後用播放器開啟avs腳本即可
PS.如果用 Media Player Classic 並且如方案安裝了 ReClock-DSF 可解除使用
,只要取消 ReClock Audio Renderer的勾勾就好了

级别: 版主
注册时间:
2002-12-02
在线时间:
0小时
发帖:
3002
只看该作者 2楼 发表于: 2003-12-27
file_info.txt內容修改例子
(1)要改進 [mp3].avi 之第00:10:20(十分二十秒時以後) 的影音不同步(影像比聲音慢) 2 秒的情形
File_Name = "[mp3].avi"
Delay_Time = 2
Offset_Start_Time = "00:10:20"
Frame_rate = 30

(2)要改進 [ac3].avi 一開始的影音不同步(影像比聲音慢) 2.8 秒的情形
File_Name = "[ac3].avi"
Delay_Time = 2.8
Offset_Start_Time = "00:00:00"
Frame_rate = 24

(3)要改進 [ra].rmvb 之第00:00:30(三十秒時以後) 的影音不同步(聲音比影像慢) 3 秒的情形
File_Name = "[ra].rmvb"
Delay_Time = -3
Offset_Start_Time = "00:00:30"
Frame_rate = 30

(4)要改進 C:\Temp\[mp3].avi 一開始的影音不同步(影像比聲音慢) 3.1 秒的情形
File_Path = "C:\Temp\"
File_Name = "[mp3].avi"
Delay_Time = 3.1
Offset_Start_Time = "00:00:00"
Frame_rate = 30

(5)要改進 [ac3].avi 之第00:20:00(二十分時以後) 的影音不同步(影像比聲音慢) 1.6 秒的情形
並且使用 [mp3].mp3 當作音訊
File_Name = "[ac3].avi"
Audio_Style = "[mp3].mp3"
Delay_Time = 1.6
Offset_Start_Time = "00:20:00"
Frame_rate = 24

注意事項:
1.Frame_rate 這裡一定要填對
2.播放 rm/rmvb 需要系統有安裝 RealMediaSplitter.ax
3.Audio_Style 可用 ac3、mp3、ra、xx.ac3、xx.mp3、xx.ra,如無影音訊分離請保持 ""
4.AviSynth_Plugins_Path 請根據你的AviSynth Plugin 所在位址修改(特別針對上述 3 需求時)
5.針對上述第 3 點分別需要用到 mpasource.dll(mp3)、ac3source.dll(ac3) 等 AviSynth Plugin

後敘:
至於avs腳本原理這裡不做解釋,有興趣者可PM me交流
如有其他使用問題或BUG可將詳細播放情形告知以利排除

级别: 版主
注册时间:
2002-12-02
在线时间:
0小时
发帖:
3002
只看该作者 3楼 发表于: 2003-12-27
[file_info.txt]

#File_Path: 影音檔播放位址(""的話表示和avs腳本及file_info.txt放在一起)。[可不填""或"x:\abc\"或"x:\"]
#File_Name: 可填寫 [.RM、.RMVB、.AVI、.MKV] 等副檔名影音檔(後綴名)。
#Delay_Time: 延遲時間 [範圍: 0 ~ x.x]
#Frame_rate: Frame per sceond。[範圍: 15、24、30、60、120]
#Audio_Style: 音訊型態。[ac3、mp3、ra、xx.ac3、xx.mp3、xx.ra]
#Offset_Start_Time: 開始延遲時間(偏移時間)。["hh:mm:ss",小時:分鐘:秒鐘]
#Property_Revision: 屬性修正旗標(這裡針對Frame_rate)。[True或False]
#AviSynth_Plugins_Path: AviSynth外掛filter的存放位址。
#注意:File_Name、Audio_Style只可出現一次"."並用於區隔副檔名用。

File_Path = ""
File_Name = "a.avi"
Audio_Style = ""

Delay_Time = 0
Offset_Start_Time = "00:00:00"

Frame_rate = 30
Property_Revision = True
If_FilePath_Exist_necessary_word = "\"
AviSynth_Plugins_Path = "C:\Program Files\AviSynth 2.5\plugins\"

级别: 版主
注册时间:
2002-12-02
在线时间:
0小时
发帖:
3002
只看该作者 4楼 发表于: 2003-12-27
[sync.avs]

SetMemoryMax(64)
Import("file_info.txt")
Exist(AviSynth_Plugins_Path + "mpasource.dll") ? \
LoadPlugin(AviSynth_Plugins_Path + "mpasource.dll") : nop
Exist(AviSynth_Plugins_Path + "MPEGDecoder.dll") ? \
LoadPlugin(AviSynth_Plugins_Path + "MPEGDecoder.dll") : nop
Exist(AviSynth_Plugins_Path + "ac3source.dll") ? \
LoadPlugin(AviSynth_Plugins_Path + "ac3source.dll") : nop

Function PropertyRevision_Frame_rate (float F_r) {
ReturnFrame_rate = (F_r == 15) ? 12 : F_r
ReturnFrame_rate = (F_r == 24) ? 23.976 : ReturnFrame_rate
ReturnFrame_rate = (F_r == 30) ? 29.970 : ReturnFrame_rate
ReturnFrame_rate = (F_r == 60) ? 59.94 : ReturnFrame_rate
ReturnFrame_rate = (F_r == 120) ? 59.94 : ReturnFrame_rate
return(default(ReturnFrame_rate, F_r))
}

Function GetFileClip (String F_N, float F_r) {
v = DirectShowSource(F_N, F_r)
ChangeFPS(v, F_r)
AssumeFrameBased(v)
AssumeTFF(v)
AssumeFPS(v, F_r, True)
return(v)
}

Function GetAudio (clip v, String F_P, String F_N, String A_S) {
##求Audio 檔名、副檔名##
A_S_FrontNameChrNum = Findstr(A_S, ".")
A_S_Temp = RightStr(A_S, (StrLen(A_S)- A_S_FrontNameChrNum))
Audio_Style = (A_S_FrontNameChrNum > 0) ? UCase(A_S_Temp) : UCase(A_S)
F_N_FrontNameChrNum = Findstr(F_N, ".")
A_N_Temp = LeftStr(F_N, F_N_FrontNameChrNum)
Audio_Name = (A_S_FrontNameChrNum == 0) ? F_P + A_N_Temp + Audio_Style : F_P + A_S
#####Audio = Vedio######
Audio_Style = (F_N == A_S) ? "Vedio" : Audio_Style
Temp_Clip_Vedio = (F_N == A_S) ? v : nop
#####Audio File存在#####
Temp_Clip_AVI = (Audio_Style == "AVI") ? v : nop
Temp_Clip_MP3 = (Audio_Style == "MP3") ? mpaSource(Audio_Name) : nop
Temp_Clip_AC3 = (Audio_Style == "AC3") ? v.ac3source(Audio_Name).AmplifydB(18,18) : nop
Temp_Clip_WAV = (Audio_Style == "WAV") ? WavSource(F_P + F_N) : nop
Temp_Clip_RA = (Audio_Style == "RA") ? DirectShowSource(Audio_Name, fps= v.framerate, seek= false, audio= True, video= True) : nop

Return_Audio = Eval("Temp_Clip_"+ Audio_Style)
return(Return_Audio)
}

Function ErrorText (int err_num) {
vedio_Subtitle = (err_num == -1) ?
\ "File_info.txt 內的 Offset_Start_Time 時間設定錯誤" :
\ (err_num == 2) ? "檔案沒發現" :
\ ""
vedio_Subtitle = vedio_Subtitle + "avs腳本無作用"
return(vedio_Subtitle)
}

Function Get_Offset_Time(String O_S_T, float F_r) {
Temp_Str = LeftStr(O_S_T, 2)
Time_Temp = Value(LeftStr(Temp_Str, 1)) * 10 + Value(RightStr(Temp_Str, 1))
Hour_Time = (Time_Temp < 60) ? Time_Temp * 360 : -1

Temp_Str = MidStr(O_S_T, 4, 2)
Time_Temp = Value(LeftStr(Temp_Str, 1)) * 10 + Value(RightStr(Temp_Str, 1))
Minute_Time = (Time_Temp < 60) ? Time_Temp * 60 : -1

Temp_Str = RightStr(O_S_T, 2)
Time_Temp = Value(LeftStr(Temp_Str, 1)) * 10 + Value(RightStr(Temp_Str, 1))
Second_Timp = (Time_Temp < 60) ? Time_Temp : -1

Time_Total = ((Hour_Time < 0) || (Minute_Time < 0) || (Second_Timp < 0)) ? -1 : Hour_Time + Minute_Time + Second_Timp
Return_Frame_Count = Int(Time_Total * F_r)
return (Return_Frame_Count)
}

#EX: Vedio_DelayAudio(Vedio, Audio, Offset_Frame, Delay_Time)
Function Vedio_DelayAudio (clip Vedio, clip Audio, Int Offset_Frame, float Delay_Time) {
Global v = Vedio
Global a = !IsClip(Audio) ? Vedio : Audio
Global O_F = Offset_Frame
Global Delay_TimeF = Int(Delay_Time * Vedio.Framerate)
#####Vedio1_NullAudio+Vedio2_Audio2#####
Function DelayTimeis_positive{
Temp_audio = BlankClip(v).Trim(O_F, O_F + Delay_TimeF- 1)
VA_temp1 = AudioDub(v, Temp_audio).Trim(O_F, O_F + Delay_TimeF- 1)
Temp_vedio = v.trim(O_F + Delay_TimeF, v.framecount).KillAudio
VA_temp2 = AudioDub(Temp_vedio, a)
return UnalignedSplice(VA_temp1, VA_temp2)
}
#####Vedio1_Audio1+Vedio2_Audio2########
Function DelayTimeis_negative {
VA_temp1 = v.Trim(O_F, v.Framecount).KillAudio
VA_temp2 = v.Trim(O_F - Delay_TimeF, v.Framecount)
return AudioDub(VA_temp1, VA_temp2)
}
###[Function Vedio_DelayAudio Start]####
Return_VA =
\ (Delay_Time < 0) ? DelayTimeis_negative :
\ (Delay_Time > 0) ? DelayTimeis_positive :
\ AudioDub(Vedio, Audio)

return Return_VA
}

#DivideVedio(Vedio, Audio, Offset_Frame, Delay_Time)
Function DivideVedio (clip v, clip a, Int O_F, float D_T) {
Return_va1 = AudioDub(v, a).Trim(0, O_F- 1)
Return_va2 = AudioDub(v, a).Trim(O_F, v.Framecount).DelayAudio(D_T)
Return_va = Return_va1 + Return_va2
return (Return_va)
}

#####[主程序開始]#####
####參數修正、判斷####
Frame_rate = Property_Revision ? PropertyRevision_Frame_rate(Frame_rate) : Frame_rate
File_Path = File_Path + If_FilePath_Exist_necessary_word
Work_Movie_File = File_Path + File_Name
Work_Audio_File = File_Path + Audio_Style
AudioFile_Exist = Exist(Work_Audio_File)

##獲得Vedio及Audio Clip##
Vedio = GetFileClip(Work_Movie_File, Frame_rate)
Audio = (AudioFile_Exist || (Audio_Style <> "")) ? GetAudio(Vedio, File_Path, File_Name, Audio_Style) : Vedio
IsClip(Audio) ? KillAudio(Vedio) : nop
Offset_Frame = (Delay_Time <> 0) ? Get_Offset_Time(Offset_Start_Time, Frame_rate) : Get_Offset_Time("00:00:00", Frame_rate)

PlayFile =
\ ((Offset_Frame == 0) && (Delay_Time == 0)) ?
\ AudioDub(Vedio, Audio) :
\ (Offset_Frame == 0) ?
\ Vedio_DelayAudio(Vedio, Audio, Offset_Frame, Delay_Time) :
\ (Offset_Frame > 0) ?
\ DivideVedio(Vedio, Audio, Offset_Frame, Delay_Time) :
\ AudioDub(Vedio, Audio)

Offset_Frame < 0 ? PlayFile.Subtitle(ErrorText(-1)) : PlayFile

级别: 骑士
注册时间:
2003-04-17
在线时间:
0小时
发帖:
1338
只看该作者 5楼 发表于: 2003-12-31
weilai,有点复杂的说;)我一般就是用DELAYAUDIO+AUDIODUB,不过多了个音画分离,其实用VMD再DUB一次,只要调整好DELAYAUDIO一样可以的~

EMULE ID:yzj[eDtoon][CHN][lh.2y.net][VeryCD]这个现在比较少用
AMULE ID:yzjamule[CHN][TLF][eDtoon][VeryCD] 持续运行中
级别: 版主
注册时间:
2002-12-02
在线时间:
0小时
发帖:
3002
只看该作者 6楼 发表于: 2003-12-31
引用
最初由 岚轩 发布
weilai,有点复杂的说;)我一般就是用DELAYAUDIO+AUDIODUB,不过多了个音画分离,其实用VMD再DUB一次,只要调整好DELAYAUDIO一样可以的~


寫完自己也這麼覺得
其實主要是邊學邊寫
再加上
.DELAYAUDIO 有一個奇怪的限制(不知說不說的上是 bug ; 用在一開始無偏移時間的使用上)
.一些自動判斷
造成的

级别: 版主
注册时间:
2002-12-02
在线时间:
0小时
发帖:
3002
只看该作者 7楼 发表于: 2004-01-03
這裡加個特例
Q:问个问题,如果rm的声音不同步是越往后不同步越严重,那该怎么做?
A:先試試 方法不行的話試試[A]方法不行的話試試[A]+
原理講解:
其實此情形用 理論因該可以解決
只是 Reclock filter 有一個限制: 應用在解碼後的 PCM 音訊
所以 rm/rmvb 不可行
此時只要用 avs 範本導入
就可透過 avs sever 達到解碼後的音訊為 PCM

file_info.txt內容修改如下
Delay_Time = 0
Offset_Start_Time = "00:00:00"
PS.如果一開始就有延遲現像請用 第3楼的第(2)例

只是真的沒看過 rm 且還會慢慢不同步的情形,所以也不能打包票

级别: 新手上路
注册时间:
2003-08-17
在线时间:
0小时
发帖:
267
只看该作者 8楼 发表于: 2004-01-14
那如果要由rm,rmvb轉換去mpg呢?我有一套动画有这问题,想轉換去vcd file.

只要幸福
即使平凡
也无所谓。

我来自马来西亚.^_^
级别: 圣骑士
注册时间:
2002-11-14
在线时间:
6小时
发帖:
1623
只看该作者 9楼 发表于: 2004-01-22
这个很有价值.
仔细琢磨下.

级别: 新手上路
注册时间:
2003-08-16
在线时间:
0小时
发帖:
50
只看该作者 10楼 发表于: 2004-01-26
哇!好东西啊!谢谢,这下我可有办法了!
级别: 小荷初露
注册时间:
2002-08-21
在线时间:
0小时
发帖:
117
只看该作者 11楼 发表于: 2004-01-27
很好的教程,感谢
级别: 新手上路
注册时间:
2004-01-27
在线时间:
0小时
发帖:
39
只看该作者 12楼 发表于: 2004-01-28
呵呵,我一般是找另外的版本下来看喽


   來啊!為我們的老去——幹盃!
   ----------Zerozf
级别: 新手上路
注册时间:
2003-03-18
在线时间:
0小时
发帖:
76
只看该作者 13楼 发表于: 2004-01-29
好强的贴````不过也太长了~!~``

有时间可以仔细慢慢研究一下`
级别: 版主
注册时间:
2002-12-02
在线时间:
0小时
发帖:
3002
只看该作者 14楼 发表于: 2004-01-29
引用
最初由 通灵者 发布
好强的贴````不过也太长了~!~``

有时间可以仔细慢慢研究一下`


沒辦法沒有合適的上傳空間
貼出.avs內容腳本並非這一帖的本意

目前正製作自動安裝版(setup.exe)
已實驗成功
未來
只要用右鍵-傳送到- xxx 就可不必改 file_info.txt 的 File_xxx 內容
就可開起使用該 .avs
只是受限於 Avisynth 的 DirectShowSource filter function 限制
Frame_rate = xx 還是要自行填寫

講解一下目前進度:
V1.15.10
.取消了 {File_Name、Audio_Style只可出現一次"."並用於區隔副檔名用} 之限制
.字幕自行載入
.使用者末端filter加載
.播放速度調整
.及多項self Function 修訂

未來目標:
.Frame_rate 的自我判讀
.GUI 介面的目標

快速回复

限150 字节
上一个 下一个