2013-11-20 17 views
1

我正在處理這個草圖,它從我的網絡攝像頭/智能手機獲取videofeed並在運行時顯示它。我想導入一個.srt轉換爲txt字幕文件從一個電影到它。我可以看到文本文件具有所有這些數字,代表實際文本之前的開始和結束字幕框架。在處理中導入字幕

下面是一個例子:

{9232}{9331}Those swings are dangerous.|Stay off there. I haven't fixed them yet. 
{9333}{9374}I think you're gonna live. 

我想這樣做是要弄清楚歐塔代碼,將

  1. 使用的數量和它們設置爲開始/結束幀在正確運行時間如同在電影中
  2. 顯示字幕
  3. 找出'|'符號如何用作符號在腳本中觸發行更改。

我想這可能已經是相當複雜的,但我只是想檢查是否有人進行過類似的東西..

我想我想要做的是救了我這樣做整個

if ((current_frame > 9232) && ((current_frame < 9331)) { 
    text("Those swings are dangerous.", 200, 500/2); 
    text("Stay off there. I haven't fixed them yet..", 200, (500/2 + 35)); 
} 

的事情每個字幕...

我很新的處理,不是熟悉的除了許多命令「的」和「如果」,在導入txt文件和無知的新手在w與數組一起操作。但我真的想在最後兩位,以找到一個不錯的方式..

以任何形式任何幫助,將不勝感激:)

乾杯, 喬治

回答

2

爲了顯示相應的字幕,你可以(對文本的牆下面的解釋,事先說一句抱歉)這樣做以下:

String[] subtitles = loadStrings("subtitles.txt"); 
int currentFrame = 0; 
int subtitleIndex = -1; 
int startFrame = -1, endFrame = -1; 
int fontSize = 10; //change to suit your taste 
String[] currentSubtitle; 
... 

//draw loop start: 
//video drawing code goes here 

if(currentFrame > endFrame){ //update which subtitle is now/next 
    subtitleIndex++; 
    startFrame = int(subtitles[subtitleIndex].split("\\}\\{")[0].substring(1)); 
    endFrame = int(subtitles[subtitleIndex].split("\\}\\{")[1].split("\\}")[0]); 
    currentSubtitle = subtitles[subtitleIndex].split("\\}")[2].split("\\|"); 
} 
if(currentFrame >= startFrame && currentFrame <= endFrame){ 
    for(int i = 0; i < currentSubtitle.length; i++){ 
    text(currentSubtitle[i], width/2, height - fontSize * (currentSubtitle.length - i)); 
    } 
} 
currentFrame++; 
//draw loop end 

可能是看起來很嚇人給你,讓這裏的一些步行通過的評論。您的程序將是一種state machine。它將處於顯示副標題的狀態,或不處於狀態。稍後我們將在設計代碼時記住這一點。首先,你需要聲明和初始化你的變量。

第一行使用loadStrings()函數,該函數讀取文本文件並返回String數組,其中陣列中的每個元素都是文件中的一行。當然,您需要更改文件名以適合您的文件。

您的代碼使用了一個名爲current_frame的變量,這是一個非常好的主意,但我已將其重命名爲currentFrame以符合java編碼慣例。我們將從零開始,稍後我們的代碼將在每個幀顯示中增加它。這個變量會告訴我們在字幕序列中的位置以及應該顯示哪個消息(如果有的話)。

因爲每個字幕開始和結束的信息都是以字符串編碼的,所以將它合併到代碼中有點棘手。現在,讓我們創建一些變量,它們表示當前「當前」字幕 - 即我們當前正在顯示還是將要顯示的字幕 - 開始和結束的時間。我們還將創建一個索引以跟蹤subtitles陣列中的哪個元素是「當前」字幕。這些變量都從-1開始,這看起來有點奇怪。儘管我們初始化了currentFrame0,但它們並沒有真正的「初始」值,至少現在不是。如果我們選擇0,那麼這不是真的,因爲第一個字幕可能不是(可能不是)在0幀開始和結束,並且任何其他正數都沒有多大意義。 -1通常用作虛擬索引,在變量實際使用之前將被替換,因此我們也會在這裏執行此操作。

現在爲最終變量:currentSubtitle。直接的想法是這是一個普通的String,而不是String陣列。但是,由於每個字幕可能需要在管道(|)符號上拆分,因此每個字幕實際上可能代表多行文本,因此我們將創建一個數組以便安全。有些字幕可能是一個單元素數組,但這很好。

現在的困難部分!

假設你的代碼中會有某種循環,每次迭代時相關的視頻幀都被繪製到屏幕上(如果滿足條件的話),字幕會被繪製在頂部。我已經忽略了視頻部分,因爲這不是你問題的一部分。

在我們做任何事情之前,我們需要記住,我們的一些變量還沒有真正的值 - 所有這些從以前的需要設置的東西。繪圖循環的基本邏輯是:1)確定是否需要繪製字幕,如果需要繪製,請繪製它; 2)確定是否需要將「當前」字幕移動到陣列中的下一個字幕。讓我們先做#2,因爲第一次通過循環,我們還不知道任何事情!移動到下一個字幕的標準(一般來說)是,如果我們超過了當前字幕的末尾:。如果這是真的,那麼我們需要將我們所有的變量轉移到下一個字幕。 subtitleIndex很簡單,我們只需添加一個即可完成。其餘的......並不那麼容易。我知道它看起來很噁心,但最後我會談論這個,以免打破流動。如果你等不及,請跳到最下面:)

之後(如有必要)更改所有變量以使它們與當前字幕相關,我們需要做一些實際的顯示。第二個if語句會檢查我們是否在當前字幕的邊框「內部」。因爲currentSubtitle變量既可以指向需要立即顯示的字幕,也可以僅指示序列中的下一個字幕,因此我們需要進行一些檢查以確定該幀是哪一個。這是第二個if聲明 - 如果我們已經過了開始和結束之前,那麼我們應該顯示小標題!回想一下,我們的currentSubtitle變量是一個數組,所以我們不能直接顯示它。我們需要遍歷它並在單獨的行上顯示每個元素。你提到了text()命令,所以我不會在這裏深入討論。棘手的位是文本的y座標,因爲它應該在多行上。我們希望第一個元素高於第二個元素,高於第三個元素等。爲此,我們將使y座標取決於我們所在的元素,標記爲i。我們可以通過更改fontSize的值來縮放行之間的差異;這將會符合你的口味。知道你設置的數字將等於一行的高度(以像素爲單位)。

現在,我不想在上面解釋這個混亂的位。此代碼取決於Stringsplit()方法,該方法在要分割的字符串上執行,並將字符串作爲指示如何分割字符串的參數 - 一個regex。爲了使startFrame脫離文件中的字幕行,我們需要沿着花括號分割它,因爲這些是數字之間的分隔符。首先,我們將在「} {」發生的任何地方 - 第一個數字之後(和第二個之前)分割字符串。因爲split()返回一個數組,我們可以使用方括號之間的索引從它引用單個字符串。我們知道,第一個數字將在第一個字符串中通過分割「} {」返回,因此我們將使用索引0。這將返回(例如)「{1234」,因爲split()將刪除您正在分解的內容。現在我們只需要在第一個字符後面出現的substring,使用int()將其轉換爲int,然後我們就完成了!

對於第二個數字,我們可以採取類似的方法。我們再次分割「} {」,這次只返回返回數組中的第二個(索引1)元素。現在,我們有一些像「9331}這些波動是當...」,我們可以再次上的「}」,選擇該數組的第一個字符串,轉換爲int,我們完成了!在這兩種情況下,我們都使用subtitles[subtitleIndex]作爲原始字符串,它表示我們在開始時使用loadStrings()加載的文件的原始輸入。請注意,在所有這些拆分過程中,subtitles中的原始字符串永遠不會更改 - split(),substring()等僅返回新的序列,並且不會修改您調用它的字符串。

我要把它留給你找出該序列中的最後一行是如何工作的:)

最後,你會發現有一堆反斜線弄亂split()電話。這是因爲split()需要一個正則表達式,而不是一個簡單的字符串。正則表達式使用了很多特殊的符號,我不會在這裏介紹它,但是如果你只是通過了split()之類的東西,比如"}{",它會嘗試解釋它,它不會像預期的那樣運行。你需要escape字符,告訴split()你不希望他們被解釋爲特殊的,你只是想要自己的字符。要做到這一點,你需要在任何需要轉義的角色之前使用反衝。但是,反斜槓本身又是一個特殊字符,所以你也需要逃避它!這導致像"\\{"這樣的東西 - 第一個反斜槓轉義第二個,它逃脫了第三個字符。請注意,|角色也需要轉義。

對不起,對文本的牆!很高興看到智能和禮貌地提出的問題,所以我想我會給出一個很好的答案作爲回報。

+0

夢幻般的答案! – mdomino