日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

批量修改字幕文件中的时间,c语言实现

發布時間:2023/12/31 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 批量修改字幕文件中的时间,c语言实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近迷上了一部美劇,權力的游戲 ,Game of Thrones.追到了第三季。可惜下到的版本都是中文字幕或者中英字幕。作為一個自以為英語還不錯的人,怎么能看中文字幕呢,中英字幕也是不行的。 不看純英文的字幕,逼格真是太低了。
可惜,能下載的帶字幕的版本都是中文字幕或者中英字幕。沒辦法,只有下了一個不帶字幕的版本,然后自己再去找純英文的字幕。
好不容易把電視劇視頻文件和純英文字幕湊齊了,正準備在純英文的語境中欣賞呢,發生了一件讓我吐血的意外。字幕的時間和視頻的時間是不匹配的。暴風影音的微調字幕的功能,最多也不能超過一分鐘。然而,這個字幕和視頻的時間差足有兩分多鐘,大概是字幕對應的那個視頻裁掉了片頭吧。照著字幕的名字去搜視頻,也沒有搜到。看來只能修改字幕中語句的時間了。

時間一旦錯了,每句對話的文本的時間都要修改,如果手動去修改的話,還不把人給累死,把字幕改好了,也沒有欣賞電影的欲望了。這種重復的程序化工作,不就是應該用計算機編程來解決嗎?看來我學了這么長時間的c語言,現在可以派上用場了。有點小興奮。

大概思路是,根據視頻中的某個語句和時間,在字幕文件中找出對應的語句和時間,兩個時間的差值就是聲音與字幕的時間差,記錄這個時間差。逐一讀取原字幕文件中的字符,如果是非時間的字符,將其原封不動的復制寫入另一個文件中;如果是顯示時間的字符,則對其進行必要的修改,加上時間差,將修改后的時間字符串寫入新字幕文件中。

因為我用的標準c,僅支持ANSI字符集,又是純英文字符,ANSI編碼也足夠了。字幕文件拷貝到c盤下,我假定你是一定有c盤的,用記事本打開,另存為ANSI編碼格式,不要理會警告。

這樣的話,字幕文件里的所有字符c語言都可以處理了。

就可以用fopen()函數打開和創建。

運行我的代碼后,在輸入框里根據提示輸入文件名。我的代碼會自動拼接上路徑名和后綴名,在c語言中,這才是完整的文件名。


這里面的關鍵問題是,要修改時間,那么如何標定時間字符串?仔細觀察字幕文件。

1
00:02:13,110 --> 00:02:15,879
<i>Fall back!</i>


2
00:03:02,662 --> 00:03:04,463
Brother?


3
00:04:25,646 --> 00:04:28,314
Did you send the ravens?


很容易發現,形如xx:xx:xx的時間字符串,最顯著的特征就是冒號。于是,打開字幕文件后,就用':'來標定時間。用習語while( (ch=fgetc(fp)) != EOF )逐一讀字符,讀到':'之后,停下來,進行修正時間的操作;如果讀的不是':',即與時間無關的字符,則用fputc(ch,fp1)將字符原封不動寫入新文件中,fp1是寫入文件的指針。

第一次讀到':’之后,代表讀的是分鐘之前的':',那么將讀文件的內位指針(這是我自己起的名字,代表文件信息結構體內指示當前讀指針位置的值)往后退3個字符長度,退到小時之前,即整個時間字符串之前,用文件掃描格式函數fsanf(fp,"%2d:%2d:%2d",&th,&tm,&ts)對整個時間字符串xx:xx:xx進行掃描,得到時間后,進行修正,再用文件打印格式函數fprintf向寫文件中打印整個時間字符串。因此,也要將寫文件的內位指針往后退2個字符長度,退到小時之前。

為什么讀文件指針退后3個字符長度,而寫文件指針退后2個字符指針,它們退后的程度不一樣呢?

因為,fgetc()除了讀了表征小時的2個字符外還多讀入了一個':',而fputc()只寫下了表征小時數的兩個字符。

讀文件指針退到小時之前以后,用文件掃描格式函數fsanf(fp,"%2d:%2d:%2d",&th,&tm,&ts)讀出原字幕中的小時、分鐘和秒,把這個時間換算成秒,加上時間的差值(也是用秒表示的)。將修正后的時間換算成xx:xx:xx的格式,向新文件中寫入即可。

完整代碼如下:

#include "stdio.h" #include "string.h"main() { char originalfullname[1024] = "c:/";//at first,the fullname contains the path; char changedfullname[1024] = "c:/Changed_";// the name of the new established subtitle file,added prefix; char inputname[1024] ;//the sheer subtitle file name; //following is the process that constructs the names of both original and changed; //just plain concatenation works; printf("please input the subtitle file name \n"); scanf("%s",inputname); strcat(originalfullname,inputname); strcat(changedfullname,inputname); char *suffix = ".srt"; strcat(originalfullname,suffix); strcat(changedfullname,suffix); // //int vh,vm,vs;//beginning time of sounding of the special subtitle in video,hour,minute,second,respectively; printf("input the beginning time of the subtitle in video\n"); printf("in format xx:xx:xx\n"); scanf("%2d:%2d:%2d",&vh,&vm,&vs); fflush(stdin);int fh,fm,fs;//beginning of the special subtitle's time in subtitle file,hour,minute,second,respectively; printf("input the beginning time of the subtitle in subtitle file\n"); printf("in format xx:xx:xx\n"); scanf("%2d:%2d:%2d",&fh,&fm,&fs);int dt;//difference of time,from subtitle file to video; dt = ( vh*3600+vm*60+vs) - (fh*3600 + fm*60 + fs); printf("the time difference is %d\n",dt);FILE *fp,*fp1;//two file pointers,one is for original subtitle file,while the other for changed subtitle file; fp = NULL; fp1 = NULL;fp = fopen(originalfullname,"r"); fp1 = fopen(changedfullname,"w+");//if no such a file exists,a new file of same name established; if (!fp || !fp1)//if fp or fp1 is a not effective file pointer,return,ending this program;{printf("file opening or file establishing failed!\n ");return;}char ch; int th,tm,ts,time;//time_hour,time_minute,time_second,and time in seconds; while( ( ch = fgetc(fp) ) != EOF )//the idiom,retrieving every character of the file;{if(ch == ':'){fseek(fp,-3L,SEEK_CUR);fseek(fp1,-2L,SEEK_CUR);fscanf(fp,"%2d:%2d:%2d",&th,&tm,&ts);time = th*3600 + tm*60 + ts;time += dt;th = time/3600;tm = (time%3600)/60;ts = time%60;//following,print the time format string.hour ,minute and second apart printed .//indeed,they have a entire printing effect as a whole;fprintf(fp1,th<=9?"0%d":"%d",th);fputc(':',fp1);fprintf(fp1,tm<=9?"0%d":"%d",tm);fputc(':',fp1);fprintf(fp1,ts<=9?"0%d":"%d",ts);continue;}fputc(ch,fp1);} fclose(fp); }


在找字幕和視頻的時間差的時候,先打開字幕文件看一下,看前面幾個對話,留下個印象,順手將字幕文件保存為ANSI編碼格式。我聽力比較菜,如果之前不留個印象的話,在視頻中,光靠聽,我是聽不清楚一句英語的。然后在視頻開頭找能聽得懂的語句,記錄下時間,再到字幕文件中找到對應語句,記錄下時間。運行代碼的時候,再輸入文件名之后,接著輸入兩個時間,就將字幕中所有語句的時間修改好了。在c盤下找到以Changed開頭下劃線加上原來文件名的字幕文件。

用暴風影音打開視頻,載入修改后的字幕文件,享受純英語語境下的大片吧。如果有一點點的不匹配,用暴風影音的提前和延遲字幕的功能就好。

當night watch的隊長質問john snow胖胖的伙伴tarly:"Did you send the ravens",隨著聲音響起,匹配的字幕適時出現在視頻下方,還是蠻有成就感的!


這雖然只是c語言編程的一個小小的例子。但是它揭示了計算機科學的幾個普遍原理:1.一切科學和技術都是為了讓人過得更好的,擁有更好的人生體驗。2.計算機和編程解決問題的核心,是對問題本身的認識和理解,比如,在這個小實例中,認識到':'是標示時間字符串的關鍵,后面就勢如破竹。同理,在大的計算機解決問題實踐中,要花更多的時間去深入理解問題的本身,是關鍵,也是加力。3.算法的重要性,在這個例子中,我找到冒號以后,將文件指針退到整個時間字符串之前,對整個時間字符串進行掃描,不僅使形式更完備,而且這樣就將文件指針推進到整個時間字符串之后,就屏蔽了秒之前那個冒號。否則,還需對兩個冒號進行鑒別,哪個是分之前的,哪個是秒之前的,如果讀到的是秒之前的冒號怎么辦,這樣就會復雜很多。
在程序對文件處理的時候,還是需要顯示一些提示,這樣以降低等待的枯燥。我選擇將修改時間的處數打印出來,再加上一些對話語句。


修改了1324處的時間,如果手動修改,真不知道修改到什么時候。計算機科學真是太強大了,我愛死你了,解救人類于重復繁瑣枯燥勞動的女神學科!
最終的完整代碼如下:

#include "stdio.h" #include "string.h"main() { char originalfullname[1024] = "c:/";//at first,the fullname contains the path; char changedfullname[1024] = "c:/Changed_";// the name of the new established subtitle file,added prefix; char inputname[1024] ;//the sheer subtitle file name; //following is the process that constructs the names of both original and changed; //just plain concatenation works; printf("please input the subtitle file name \n"); scanf("%s",inputname); strcat(originalfullname,inputname); strcat(changedfullname,inputname); char *suffix = ".srt"; strcat(originalfullname,suffix); strcat(changedfullname,suffix); // //int vh,vm,vs;//beginning time of sounding of the special subtitle in video,hour,minute,second,respectively; printf("input the beginning time of the statement in video\n"); printf("in format xx:xx:xx\n"); scanf("%2d:%2d:%2d",&vh,&vm,&vs); fflush(stdin);int fh,fm,fs;//the beginning of subtitle time in subtitle file,hour,minute,second,respectively; printf("input the beginning time of the subtitle in subtitle file\n"); printf("in format xx:xx:xx\n"); scanf("%2d:%2d:%2d",&fh,&fm,&fs);int dt;//difference of time,from subtitle file to video; dt = ( vh*3600+vm*60+vs) - (fh*3600 + fm*60 + fs); printf("the time difference is %d\n",dt);FILE *fp,*fp1;//two file pointers,one is for original subtitle file,while the other for modified subtitle file,//which should be newly established. fp = NULL; fp1 = NULL; fp = fopen(originalfullname,"r"); fp1 = fopen(changedfullname,"w+");//if no such a file exists,a new file of same name established; if (!fp || !fp1)//if fp or fp1 is an ineffective file pointer,return,ending this program;{printf("file opening or file establishing failed!\n ");return;}char ch; int th,tm,ts,time;//time_hour,time_minute,time_second,and time in seconds; int i; i=0; while( ( ch = fgetc(fp) ) != EOF )//the idiom,retrieving every character of the file;{if(ch == ':'){fseek(fp,-3L,SEEK_CUR);//backward ,in front of the time string in read file;fseek(fp1,-2L,SEEK_CUR);//backward,prepared for writing time anew entirely;fscanf(fp,"%2d:%2d:%2d",&th,&tm,&ts);//get the hour ,minute and second of the original timetime = th*3600 + tm*60 + ts;time += dt;//renew the time ,by plus the difference;//convert the time, for the format , hour:minute:second;th = time/3600;tm = (time%3600)/60;ts = time%60;//following,print the time format string.hour ,minute and second apart printed .//indeed,they have a entire printing effect as a whole;fprintf(fp1,th<=9?"0%d":"%d",th);//if the value less than 10,in form : 0value,for example,7 is 07;fputc(':',fp1);fprintf(fp1,tm<=9?"0%d":"%d",tm);fputc(':',fp1);fprintf(fp1,ts<=9?"0%d":"%d",ts);i += 1;printf("your little program has changed %d ",i);printf(i>1?"places":"place");printf(" of time\n");continue;}fputc(ch,fp1);} fclose(fp); fclose(fp1); printf("enjoy your films!my lady or sir!\n"); getchar(); }
為了方便沒有裝c語言編輯器的同學,我把我編譯過的應用程序changesubtime.exe上傳到我的新浪微盤了。下載地址?下載地址

下載之后,根據以下步驟就可以批量修改字幕時間了。

1.將字幕文件拷到c盤(不要放在任何文件夾里面)。

2.運行changesubtime.exe應用程序,根據提示輸入文件名。

3.打開電影,找到一條字幕,記下它的開始時間。在程序中輸入,注意格式是兩個數字間隔冒號的。

4.打開字幕文件,記事本方式,找到那條字幕,記錄字幕的開始時間。保存,關閉記事本。在程序中輸入剛才記錄的時間。

5.在c盤中找到修改過的字幕文件,以Changed開頭,下劃線后帶的是原來的文件名。將它和電影關聯起來。

享受純英文環境下的視覺大片吧。




總結

以上是生活随笔為你收集整理的批量修改字幕文件中的时间,c语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。