[xiph-commits] r16336 - in trunk/ffmpeg2theora: . frontend frontend/theoraenc src
j at svn.xiph.org
j at svn.xiph.org
Sun Jul 26 00:33:09 PDT 2009
Author: j
Date: 2009-07-26 00:33:08 -0700 (Sun, 26 Jul 2009)
New Revision: 16336
Added:
trunk/ffmpeg2theora/frontend/theoraenc/addSubtitlesDialog.py
Modified:
trunk/ffmpeg2theora/frontend/Simple Theora Encoder.py
trunk/ffmpeg2theora/frontend/theoraenc/addVideoDialog.py
trunk/ffmpeg2theora/frontend/theoraenc/theoraenc.py
trunk/ffmpeg2theora/src/ffmpeg2theora.c
trunk/ffmpeg2theora/src/subtitles.c
trunk/ffmpeg2theora/src/subtitles.h
trunk/ffmpeg2theora/src/theorautils.c
trunk/ffmpeg2theora/subtitles.txt
Log:
add subtitles to python frontend
Modified: trunk/ffmpeg2theora/frontend/Simple Theora Encoder.py
===================================================================
--- trunk/ffmpeg2theora/frontend/Simple Theora Encoder.py 2009-07-25 22:52:38 UTC (rev 16335)
+++ trunk/ffmpeg2theora/frontend/Simple Theora Encoder.py 2009-07-26 07:33:08 UTC (rev 16336)
@@ -119,6 +119,16 @@
if key in options and options[key]:
settings.append('--%s' % key)
settings.append("%s" % float(options[key]))
+ if 'subtitles' in options and options['subtitles']:
+ for s in options['subtitles']:
+ settings.append('--subtitles')
+ settings.append('%s' % s['file'])
+ settings.append('--subtitles-language')
+ settings.append('%s' % s['language'])
+ settings.append('--subtitles-category')
+ settings.append('%s' % s['category'])
+ settings.append('--subtitles-encoding')
+ settings.append('%s' % s['encoding'])
return settings
def addItemThread(self, item):
@@ -167,7 +177,7 @@
self.removeItem.Enable()
def OnClickAdd(self, event):
- result = addVideoDialog(self)
+ result = addVideoDialog(self, theoraenc.hasKate)
time.sleep(0.5)
if result['ok']:
self.addItemToQueue(result['videoFile'], result)
Added: trunk/ffmpeg2theora/frontend/theoraenc/addSubtitlesDialog.py
===================================================================
--- trunk/ffmpeg2theora/frontend/theoraenc/addSubtitlesDialog.py (rev 0)
+++ trunk/ffmpeg2theora/frontend/theoraenc/addSubtitlesDialog.py 2009-07-26 07:33:08 UTC (rev 16336)
@@ -0,0 +1,242 @@
+# -*- coding: utf-8 -*-
+# vi:si:et:sw=2:sts=2:ts=2
+
+import os
+from os.path import basename
+import time
+
+import wx
+#import wx.lib.langlistctrl
+#from wx.lib.langlistctrl import GetWxIdentifierForLanguage
+from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin
+
+# on my box, I only get two versions of en, and two languages I'd never heard of, and keyboard input is unavailable
+# to override for a language not in the list, so we don't use it, though it'd be nice as languages names would be
+# translated, etc.
+# After installing all locales, I don't even get some non obscure locales.
+# And it doesn't seem to use ISO 639-1 tags anyway, but wxWidgets specific enums.
+# Therefore, we use a "ComboBox" widget instead, and build a list of languages from a known set plus parsing
+# the output of 'locale -a' to ensure we get the user's own language, if set (and also plenty of others if using
+# a distro that spams the locale database with lots of unused ones); keyboard input overrides is available.
+#use_langlistctrl=False
+
+class SubtitlesProperties(wx.Dialog):
+ def __init__(
+ self, parent, ID, title,
+ language, category, encoding, file,
+ size=wx.DefaultSize, pos=wx.DefaultPosition,
+ style=wx.DEFAULT_DIALOG_STYLE,
+ ):
+ pre = wx.PreDialog()
+ pre.Create(parent, ID, title, pos, size, style)
+ self.PostCreate(pre)
+
+ # defaults
+ if language == '':
+ language = 'en'
+ if category == '':
+ category = 'SUB'
+ if encoding == '':
+ encoding = 'UTF-8'
+
+ padding = 4
+
+ mainBox = wx.BoxSizer(wx.VERTICAL)
+ mainBox.AddSpacer((8, 16))
+
+ # file
+ self.btnSubtitlesFile = wx.Button(self, size=(380, -1))
+ self.btnSubtitlesFile.SetLabel('Select...')
+ self.Bind(wx.EVT_BUTTON, self.OnClickSubtitlesFile, self.btnSubtitlesFile)
+ self.addProperty(mainBox, 'File', self.btnSubtitlesFile)
+
+ # language
+# if use_langlistctrl:
+# self.languageWidget = wx.lib.langlistctrl.LanguageListCtrl(self, -1, style=wx.LC_REPORT, size=(380,140))
+# else:
+# self.languageWidget = wx.ComboBox(self, -1, language, (380,-1), wx.DefaultSize, self.BuildLanguagesList(), wx.CB_SIMPLE)
+ self.languageWidget = wx.ComboBox(self, -1, language, (380,-1), wx.DefaultSize, self.BuildLanguagesList(), wx.CB_SIMPLE)
+ self.addProperty(mainBox, 'Language', self.languageWidget, self.OnLanguageHelp)
+
+ # category
+ categories = ['SUB', 'CC', 'TRX', 'LRC'] # TODO: change when Silvia's list is final
+ self.categoryWidget = wx.ComboBox(self, -1, category, (80,-1), wx.DefaultSize, categories, wx.CB_SIMPLE)
+ self.addProperty(mainBox, 'Category', self.categoryWidget, self.OnCategoryHelp)
+
+ # encoding
+ encodings = ['UTF-8', 'ISO-8859-1']
+ self.encodingWidget = wx.Choice(self, -1, (80,-1), choices=encodings, name=encoding)
+ self.addProperty(mainBox, 'Encoding', self.encodingWidget, self.OnEncodingHelp)
+
+ #Buttons
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ mainBox.Add(hbox)
+ hbox.AddSpacer((8, 16))
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ mainBox.Add(hbox)
+ hbox.AddSpacer((280, 10))
+ self.btnCancel = wx.Button(self, wx.ID_CANCEL)
+ self.btnCancel.SetLabel('Cancel')
+ hbox.Add(self.btnCancel, 0, wx.EXPAND|wx.ALL, padding)
+
+ self.btnOK = wx.Button(self, wx.ID_OK)
+ self.btnOK.SetDefault()
+ self.btnOK.Disable()
+ self.btnOK.SetLabel('OK')
+ hbox.Add(self.btnOK, 0, wx.EXPAND|wx.ALL, padding)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ mainBox.Add(hbox)
+ hbox.AddSpacer((8, 8))
+
+ self.SetSizerAndFit(mainBox)
+
+ # preselect file, if any
+ if file and file != '' and os.path.exists(file):
+ self.selectSubtitlesFile(file)
+
+ def addProperty(self, mainBox, name, widget, help=None):
+ padding = 4
+ vspacer = 40
+ hspacer = 80
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ mainBox.Add(hbox, 0, padding)
+ hbox.AddSpacer((8, 8))
+ label = wx.StaticText(self, -1, name)
+ label.SetMinSize((hspacer,vspacer))
+ hbox.Add(label, 0, wx.EXPAND|wx.ALL, padding)
+ hbox.Add(widget, 0, padding)
+ if help:
+ hbox.AddSpacer((16, 0))
+ btnHelp = wx.Button(self, size=(80, -1))
+ btnHelp.SetLabel('More info...')
+ self.Bind(wx.EVT_BUTTON, help, btnHelp)
+ hbox.Add(btnHelp, 0, padding)
+ hbox.AddSpacer((8, 8))
+
+ def OnCategoryHelp(self, event):
+ self.DisplayHelp(
+ 'The category is a string representing the semantics of the text in a Kate stream.\n'+
+ 'These codes include:\n'+
+ ' SUB: text subtitles\n'+
+ ' CC: closed captions\n'+
+ ' TRX: transcript of a speech\n'+
+ ' LRC: lyrics\n'+
+ 'If the category needed is not available in the list, a custom one may be entered.\n')
+
+ def OnLanguageHelp(self, event):
+ self.DisplayHelp(
+ 'Language is an ISO 639-1 or RFC 3066 language tag.\n'+
+ 'Usually, these are two letter language tags (eg, "en", or "de"), '+
+ 'optionally followed by a hypen (or underscore) and a country code (eg, "en_GB", "de_DE")\n'+
+ 'If the language tag needed is not available in the list, a custom one may be entered.\n')
+
+ def OnEncodingHelp(self, event):
+ self.DisplayHelp(
+ 'Kate streams are encoded in UTF-8 (a Unicode character encoding that allows to represent '+
+ 'pretty much any existing script.\n'+
+ 'If the input file is not already encoded in UTF-8, it will need converting to UTF-8 first.\n'+
+ 'ffmpeg2theora can convert ISO-8859-1 (also known as latin1) encoding directly.\n'+
+ 'Files in other encodings will have to be converted manually in order to be used. See the '+
+ 'subtitles.txt documentation for more information on how to manually convert files.\n')
+
+ def DisplayHelp(self, msg):
+ wx.MessageBox(msg, 'More info...', style=wx.OK|wx.CENTRE)
+
+ def OnClickSubtitlesFile(self, event):
+ wildcard = "SubRip files|*.SRT;*.srt|All Files (*.*)|*.*"
+ dialogOptions = dict()
+ dialogOptions['message'] = 'Add subtitles..'
+ dialogOptions['wildcard'] = wildcard
+ dialog = wx.FileDialog(self, **dialogOptions)
+ if dialog.ShowModal() == wx.ID_OK:
+ filename = dialog.GetFilename()
+ dirname = dialog.GetDirectory()
+ self.selectSubtitlesFile(os.path.join(dirname, filename))
+ else:
+ filename=None
+ dialog.Destroy()
+ return filename
+
+ def selectSubtitlesFile(self, subtitlesFile):
+ self.subtitlesFile = subtitlesFile
+ lValue = subtitlesFile
+ lLength = 45
+ if len(lValue) > lLength:
+ lValue = "..." + lValue[-lLength:]
+ self.btnSubtitlesFile.SetLabel(lValue)
+ self.btnOK.Enable()
+
+ def BuildLanguagesList(self):
+ # start with a known basic set
+ languages = ['en', 'ja', 'de', 'fr', 'it', 'es', 'cy', 'ar', 'cn', 'pt', 'ru']
+ # add in whatever's known from 'locale -a' - this works fine if locale isn't found,
+ # but i'm not sure what that'll do if we get another program named locale that spews
+ # random stuff to stdout :)
+ f = os.popen('locale -a')
+ line = f.readline()
+ while line:
+ line = self.ExtractLanguage(line)
+ if line != '' and line != 'C' and line != 'POSIX':
+ languages.append(line)
+ line = f.readline()
+ f.close()
+ #oneliner from german python forum => unique list
+ languages = [languages[i] for i in xrange(len(languages)) if languages[i] not in languages[:i]]
+ languages.sort()
+ return languages
+
+ def ExtractLanguage(self, line):
+ line = line.split('.')[0] # stop at a dot
+ line = line.split(' ')[0] # stop at a space
+ line = line.split('@')[0] # stop at a @
+ line = line.split('\t')[0] # stop at a tab
+ line = line.split('\n')[0] # stop at a newline
+ line = line.split('\r')[0] # Mac or Windows
+ return line
+
+def addSubtitlesPropertiesDialog(parent, language, category, encoding, file):
+ dlg = SubtitlesProperties(parent, -1, "Add subtitles", language, category, encoding, file, size=(490, 560), style=wx.DEFAULT_DIALOG_STYLE)
+ dlg.CenterOnScreen()
+ val = dlg.ShowModal()
+ result = dict()
+ if val == wx.ID_OK:
+ result['ok'] = True
+ result['subtitlesFile'] = dlg.subtitlesFile
+# if use_langlistctrl:
+# result['subtitlesLanguage'] = GetWxIdentifierForLanguage(dlg.languageWidget.GetLanguage())
+# else:
+# result['subtitlesLanguage'] = dlg.languageWidget.GetValue()
+ result['subtitlesLanguage'] = dlg.languageWidget.GetValue()
+ result['subtitlesCategory'] = dlg.categoryWidget.GetValue()
+ result['subtitlesEncoding'] = dlg.encodingWidget.GetStringSelection()
+ print result
+ else:
+ result['ok'] = False
+ dlg.Destroy()
+ return result
+
+
+class SubtitlesList(wx.ListCtrl, ListCtrlAutoWidthMixin):
+ def __init__(self, parent):
+ wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
+ ListCtrlAutoWidthMixin.__init__(self)
+
+ self.ClearAll()
+ self.InsertColumn(0, "Language")
+ self.InsertColumn(1, "Category")
+ self.InsertColumn(2, "Encoding")
+ self.InsertColumn(3, "Name")
+ self.SetColumnWidth(0, 80)
+ self.SetColumnWidth(1, 80)
+ self.SetColumnWidth(2, 80)
+ self.SetColumnWidth(3, 80)
+
+ def ResizeFilenameColumn(self):
+ if self.GetItemCount() > 0:
+ self.resizeLastColumn(1024)
+ else:
+ self.resizeLastColumn(0)
+
Modified: trunk/ffmpeg2theora/frontend/theoraenc/addVideoDialog.py
===================================================================
--- trunk/ffmpeg2theora/frontend/theoraenc/addVideoDialog.py 2009-07-25 22:52:38 UTC (rev 16335)
+++ trunk/ffmpeg2theora/frontend/theoraenc/addVideoDialog.py 2009-07-26 07:33:08 UTC (rev 16336)
@@ -1,15 +1,16 @@
# -*- coding: utf-8 -*-
-# vi:si:et:sw=2:sts=2:ts=2
+# vi:si:et:sw=2:sts=2:ts=2
import os
from os.path import basename
import time
+from addSubtitlesDialog import addSubtitlesPropertiesDialog, SubtitlesList
import wx
class AddVideoDialog(wx.Dialog):
def __init__(
- self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition,
+ self, parent, ID, title, hasKate, size=wx.DefaultSize, pos=wx.DefaultPosition,
style=wx.DEFAULT_DIALOG_STYLE,
):
@@ -145,6 +146,54 @@
hbox = wx.BoxSizer(wx.HORIZONTAL)
mainBox.Add(hbox)
+ # subtitles ('add' button and list)
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ mainBox.Add(hbox)
+ label = wx.StaticText(self, -1, "Subtitles")
+ hbox.AddSpacer((12, 10))
+ hbox.Add(label, 0, wx.EXPAND|wx.ALL, padding)
+
+ hbox = wx.BoxSizer(wx.HORIZONTAL)
+ mainBox.Add(hbox)
+
+ hbox.AddSpacer((section_padding, 10))
+
+ if hasKate:
+ vbox = wx.BoxSizer(wx.VERTICAL)
+ hbox.Add(vbox)
+
+ subtitlesButtons_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ vbox.Add(subtitlesButtons_hbox)
+
+ self.btnSubtitlesAdd = wx.Button(self, size=(120, -1))
+ self.btnSubtitlesAdd.SetLabel('Add...')
+ self.Bind(wx.EVT_BUTTON, self.OnClickSubtitlesAdd, self.btnSubtitlesAdd)
+ subtitlesButtons_hbox.Add(self.btnSubtitlesAdd, 0, wx.EXPAND|wx.ALL, padding)
+
+ self.btnSubtitlesRemove = wx.Button(self, size=(120, -1))
+ self.btnSubtitlesRemove.SetLabel('Remove')
+ self.Bind(wx.EVT_BUTTON, self.OnClickSubtitlesRemove, self.btnSubtitlesRemove)
+ self.btnSubtitlesRemove.Disable()
+ subtitlesButtons_hbox.Add(self.btnSubtitlesRemove, 0, wx.EXPAND|wx.ALL, padding)
+
+ self.btnSubtitlesProperties = wx.Button(self, size=(120, -1))
+ self.btnSubtitlesProperties.SetLabel('Properties')
+ self.Bind(wx.EVT_BUTTON, self.OnClickSubtitlesProperties, self.btnSubtitlesProperties)
+ self.btnSubtitlesProperties.Disable()
+ subtitlesButtons_hbox.Add(self.btnSubtitlesProperties, 0, wx.EXPAND|wx.ALL, padding)
+
+ #self.subtitles = wx.ListCtrl(self, -1, style=wx.LC_REPORT)
+ self.subtitles = SubtitlesList(self)
+ self.subtitles.Bind(wx.EVT_LIST_ITEM_SELECTED, self.CheckSubtitlesSelection)
+ self.subtitles.Bind(wx.EVT_LEFT_DCLICK, self.OnClickSubtitlesProperties)
+ self.subtitles.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.CheckSubtitlesSelection)
+ self.subtitles.Bind(wx.EVT_KILL_FOCUS, self.CheckSubtitlesSelection)
+ vbox.Add(self.subtitles, 0, wx.EXPAND|wx.ALL, padding)
+
+ else:
+ self.subtitles = None
+ hbox.Add(wx.StaticText(self, -1, "ffmpeg2theora doesn't seem to be built with subtitles support.\nSee documentation for how to enable subtitles.\n"))
+
'''
#Metadata
label = wx.StaticText(self, -1, "Metadata")
@@ -257,14 +306,61 @@
def selectVideoFile(self, videoFile):
self.videoFile = videoFile
lValue = videoFile
- lLenght = 45
- if len(lValue) > lLenght:
- lValue = "..." + lValue[-lLenght:]
+ lLength = 45
+ if len(lValue) > lLength:
+ lValue = "..." + lValue[-lLength:]
self.btnVideoFile.SetLabel(lValue)
self.btnOK.Enable()
-def addVideoDialog(parent):
- dlg = AddVideoDialog(parent, -1, "Add Video", size=(490, 560), style=wx.DEFAULT_DIALOG_STYLE)
+ def CheckSubtitlesSelection(self, event):
+ idx=self.subtitles.GetFirstSelected()
+ if idx<0:
+ self.btnSubtitlesRemove.Disable()
+ self.btnSubtitlesProperties.Disable()
+ else:
+ self.btnSubtitlesRemove.Enable()
+ self.btnSubtitlesProperties.Enable()
+ self.subtitles.ResizeFilenameColumn()
+
+ def OnClickSubtitlesAdd(self, event):
+ self.subtitles.Append(['', '', '', ''])
+ if not self.ChangeSubtitlesProperties(self.subtitles.GetItemCount()-1):
+ self.subtitles.DeleteItem(self.subtitles.GetItemCount()-1)
+ self.subtitles.ResizeFilenameColumn()
+
+ def OnClickSubtitlesRemove(self, event):
+ while 1:
+ idx=self.subtitles.GetFirstSelected()
+ if idx<0:
+ break
+ self.subtitles.DeleteItem(idx)
+ self.CheckSubtitlesSelection(event)
+
+ def OnClickSubtitlesProperties(self, event):
+ idx=self.subtitles.GetFirstSelected()
+ if idx<0:
+ return
+ self.ChangeSubtitlesProperties(idx)
+
+ def ChangeSubtitlesProperties(self, idx):
+ language = self.subtitles.GetItem(idx, 0).GetText()
+ category = self.subtitles.GetItem(idx, 1).GetText()
+ encoding = self.subtitles.GetItem(idx, 2).GetText()
+ file = self.subtitles.GetItem(idx, 3).GetText()
+ result = addSubtitlesPropertiesDialog(self, language, category, encoding, file)
+ time.sleep(0.5) # why ? race condition ?
+ if result['ok']:
+ self.subtitles.SetStringItem(idx, 0, result['subtitlesLanguage'])
+ self.subtitles.SetStringItem(idx, 1, result['subtitlesCategory'])
+ self.subtitles.SetStringItem(idx, 2, result['subtitlesEncoding'])
+ self.subtitles.SetStringItem(idx, 3, result['subtitlesFile'])
+ return True
+ else:
+ return False
+
+
+def addVideoDialog(parent, hasKate):
+ dlg = AddVideoDialog(parent, -1, "Add Video", hasKate, size=(490, 560), style=wx.DEFAULT_DIALOG_STYLE)
dlg.CenterOnScreen()
val = dlg.ShowModal()
result = dict()
@@ -274,6 +370,16 @@
for key in ('width', 'height', 'videoquality', 'videobitrate', 'framerate',
'audioquality', 'audiobitrate', 'samplerate'):
result[key] = getattr(dlg, key).GetValue()
+ # subtitles
+ if dlg.subtitles:
+ for idx in range(dlg.subtitles.GetItemCount()):
+ if not 'subtitles' in result:
+ result['subtitles'] = []
+ language = dlg.subtitles.GetItem(idx, 0).GetText()
+ category = dlg.subtitles.GetItem(idx, 1).GetText()
+ encoding = dlg.subtitles.GetItem(idx, 2).GetText()
+ file = dlg.subtitles.GetItem(idx, 3).GetText()
+ result['subtitles'].append({'encoding':encoding, 'language':language, 'category':category, 'file':file})
print result
else:
result['ok'] = False
Modified: trunk/ffmpeg2theora/frontend/theoraenc/theoraenc.py
===================================================================
--- trunk/ffmpeg2theora/frontend/theoraenc/theoraenc.py 2009-07-25 22:52:38 UTC (rev 16335)
+++ trunk/ffmpeg2theora/frontend/theoraenc/theoraenc.py 2009-07-26 07:33:08 UTC (rev 16336)
@@ -13,6 +13,32 @@
resourcePath = abspath(dirname(__file__))
+def probe_ffmpeg2theora():
+ appname = 'ffmpeg2theora'
+ if os.name == 'nt':
+ appname = appname + '.exe'
+ ffmpeg2theora = join(resourcePath, appname)
+ if not exists(ffmpeg2theora):
+ # ffmpeg2theora is likely in $resourcePath/../.. since we're in frontend
+ ffmpeg2theora = join(resourcePath, join('../../', appname))
+ if not exists(ffmpeg2theora):
+ ffmpeg2theora = join('./', appname)
+ if not exists(ffmpeg2theora):
+ ffmpeg2theora = appname
+ return ffmpeg2theora
+
+def probe_kate(ffmpeg2theora):
+ hasKate = False
+ cmd = ffmpeg2theora + ' --help'
+ f = os.popen(cmd)
+ line = f.readline()
+ while line:
+ if line.find('Subtitles options:') >= 0:
+ hasKate = True
+ line = f.readline()
+ f.close()
+ return hasKate
+
def timestr(seconds):
hours = int(seconds/3600)
minutes = int((seconds-( hours*3600 ))/60)
@@ -22,20 +48,15 @@
class TheoraEnc:
settings = []
p = None
+
def __init__(self, inputFile, outputFile, updateGUI):
self.inputFile = inputFile
self.outputFile = outputFile
self.updateGUI = updateGUI
- appname = 'ffmpeg2theora'
- if os.name == 'nt':
- appname = appname + '.exe'
- self.ffmpeg2theora = join(resourcePath, appname)
- if not exists(self.ffmpeg2theora):
- self.ffmpeg2theora = appname
def commandline(self):
cmd = []
- cmd.append(self.ffmpeg2theora)
+ cmd.append(ffmpeg2theora)
cmd.append('--frontend')
for e in self.settings:
cmd.append(e)
@@ -74,23 +95,33 @@
line = f.readline()
info = dict()
status = ''
+ self.warning_timeout = 0
while line:
+ now = time.time()
try:
data = simplejson.loads(line)
for key in data:
info[key] = data[key]
- if 'position' in info:
- if 'duration' in info and float(info['duration']):
- encoded = "encoding % 3d %% done " % ((float(info['position']) / float(info['duration'])) * 100)
- else:
- encoded = "encoded %s/" % timestr(float(info['position']))
- if float(info['remaining'])>0:
- status = encoded + '/ '+ timestr(float(info['remaining']))
- else:
- status = encoded
+ if 'WARNING' in info:
+ status = info['WARNING']
+ self.warning_timeout = now + 3
+ del info['WARNING']
else:
- status = "encoding.."
- self.updateGUI(status)
+ status=None
+ if now >= self.warning_timeout:
+ if 'position' in info:
+ if 'duration' in info and float(info['duration']):
+ encoded = "encoding % 3d %% done " % ((float(info['position']) / float(info['duration'])) * 100)
+ else:
+ encoded = "encoded %s/" % timestr(float(info['position']))
+ if float(info['remaining'])>0:
+ status = encoded + '/ '+ timestr(float(info['remaining']))
+ else:
+ status = encoded
+ else:
+ status = "encoding.."
+ if status != None:
+ self.updateGUI(status)
except:
pass
line = f.readline()
@@ -102,3 +133,6 @@
self.updateGUI(info.get('result', 'Encoding failed.'))
return False
+ffmpeg2theora = probe_ffmpeg2theora()
+hasKate = probe_kate(ffmpeg2theora)
+
Modified: trunk/ffmpeg2theora/src/ffmpeg2theora.c
===================================================================
--- trunk/ffmpeg2theora/src/ffmpeg2theora.c 2009-07-25 22:52:38 UTC (rev 16335)
+++ trunk/ffmpeg2theora/src/ffmpeg2theora.c 2009-07-26 07:33:08 UTC (rev 16336)
@@ -857,7 +857,7 @@
info.with_kate=1;
}
}
- else if (load_subtitles(ks,this->ignore_non_utf8)>0) {
+ else if (load_subtitles(ks,this->ignore_non_utf8,info.frontend)>0) {
#ifdef DEBUG
printf("Muxing Kate stream %d from %s as %s %s\n",
i,ks->filename,
@@ -1350,7 +1350,7 @@
t = 0;
}
if (utf8 && t >= 0)
- add_subtitle_for_stream(this->kate_streams, this->n_kate_streams, pkt.stream_index, t, duration, utf8, utf8len);
+ add_subtitle_for_stream(this->kate_streams, this->n_kate_streams, pkt.stream_index, t, duration, utf8, utf8len, info.frontend);
if (allocated_utf8) free(allocated_utf8);
}
else {
@@ -1640,7 +1640,7 @@
" supported are " SUPPORTED_ENCODINGS "\n"
" --subtitles-language language set subtitles language (de, en_GB, etc)\n"
" --subtitles-category category set subtitles category (default \"subtitles\")\n"
- " --subtitles-ignore-non-utf8 ignores any non utf-8 sequence in utf-8 text\n"
+ " --subtitles-ignore-non-utf8 ignores any non UTF-8 sequence in UTF-8 text\n"
" --nosubtitles disables subtitles from input\n"
"\n"
#endif
@@ -1900,11 +1900,11 @@
info.with_kate=1;
break;
case SUBTITLES_ENCODING_FLAG:
- if (!strcmp(optarg,"utf-8")) set_subtitles_encoding(convert,ENC_UTF8);
- if (!strcmp(optarg,"utf8")) set_subtitles_encoding(convert,ENC_UTF8);
- else if (!strcmp(optarg,"iso-8859-1")) set_subtitles_encoding(convert,ENC_ISO_8859_1);
- else if (!strcmp(optarg,"latin1")) set_subtitles_encoding(convert,ENC_ISO_8859_1);
- else report_unknown_subtitle_encoding(optarg);
+ if (!strcasecmp(optarg,"utf-8")) set_subtitles_encoding(convert,ENC_UTF8);
+ else if (!strcasecmp(optarg,"utf8")) set_subtitles_encoding(convert,ENC_UTF8);
+ else if (!strcasecmp(optarg,"iso-8859-1")) set_subtitles_encoding(convert,ENC_ISO_8859_1);
+ else if (!strcasecmp(optarg,"latin1")) set_subtitles_encoding(convert,ENC_ISO_8859_1);
+ else report_unknown_subtitle_encoding(optarg, info.frontend);
flag = -1;
break;
case SUBTITLES_IGNORE_NON_UTF8_FLAG:
Modified: trunk/ffmpeg2theora/src/subtitles.c
===================================================================
--- trunk/ffmpeg2theora/src/subtitles.c 2009-07-25 22:52:38 UTC (rev 16335)
+++ trunk/ffmpeg2theora/src/subtitles.c 2009-07-26 07:33:08 UTC (rev 16336)
@@ -26,6 +26,7 @@
#include <getopt.h>
#include <math.h>
#include <errno.h>
+#include <stdarg.h>
#include "libavformat/avformat.h"
@@ -37,6 +38,26 @@
#include "subtitles.h"
+static void warn(FILE *frontend, const char *file, unsigned int line, const char *format,...)
+{
+ va_list ap;
+ va_start(ap,format);
+ if (frontend) {
+ fprintf(frontend,"{\"WARNING\": \"");
+ vfprintf(frontend,format,ap);
+ fprintf(frontend,"\"}\n");
+ }
+ else {
+ if (file)
+ fprintf(stderr, "WARNING - %s:%u: ", file, line);
+ else
+ fprintf(stderr, "WARNING - ");
+ vfprintf(stderr,format,ap);
+ fprintf(stderr,"\n");
+ }
+ va_end(ap);
+}
+
/**
* adds a new kate stream structure
*/
@@ -125,11 +146,13 @@
}
-void report_unknown_subtitle_encoding(const char *name)
+void report_unknown_subtitle_encoding(const char *name, FILE *frontend)
{
- fprintf(stderr, "Unknown character encoding: %s\n",name);
- fprintf(stderr, "Valid character encodings are:\n");
- fprintf(stderr, " " SUPPORTED_ENCODINGS "\n");
+ warn(frontend, NULL, 0, "Unknown character encoding: %s",name);
+ if (!frontend) {
+ fprintf(stderr, "Valid character encodings are:\n");
+ fprintf(stderr, " " SUPPORTED_ENCODINGS "\n");
+ }
}
#ifdef HAVE_KATE
@@ -152,7 +175,7 @@
}
/* very simple implementation when no iconv */
-static char *convert_subtitle_to_utf8(F2T_ENCODING encoding,char *text,int ignore_non_utf8)
+static char *convert_subtitle_to_utf8(F2T_ENCODING encoding,char *text,int ignore_non_utf8, FILE *frontend)
{
size_t nbytes;
char *ptr;
@@ -163,10 +186,10 @@
switch (encoding) {
case ENC_UNSET:
- /* we don't know what encoding this is, assume utf-8 and we'll yell if it ain't */
+ /* we don't know what encoding this is, assume UTF-8 and we'll yell if it ain't */
/* fall through */
case ENC_UTF8:
- /* nothing to do, already in utf-8 */
+ /* nothing to do, already in UTF-8 */
if (ignore_non_utf8) {
/* actually, give the user the option of just ignoring non UTF8 characters */
char *wptr;
@@ -175,7 +198,7 @@
nbytes = strlen(text)+1;
newtext=(char*)malloc(nbytes);
if (!newtext) {
- fprintf(stderr, "WARNING - Memory allocation failed - cannot convert text\n");
+ warn(frontend, NULL, 0, "Memory allocation failed - cannot convert text");
return NULL;
}
ptr = text;
@@ -187,7 +210,7 @@
/* valid character */
ret=kate_text_set_character(kate_utf8, ret, &wptr, &wlen0);
if (ret<0) {
- fprintf(stderr, "WARNING - failed to filter utf8 text: %s\n", text);
+ warn(frontend, NULL, 0, "Failed to filter utf8 text: %s", text);
free(newtext);
return NULL;
}
@@ -202,7 +225,7 @@
}
if (errors) {
- fprintf(stderr, "WARNING - Found non utf8 character(s) in string %s, scrubbed out\n", text);
+ warn(frontend, NULL, 0, "Found non utf8 character(s) in string %s, scrubbed out", text);
}
}
else {
@@ -219,7 +242,7 @@
}
newtext=(char*)malloc(1+nbytes);
if (!newtext) {
- fprintf(stderr, "WARNING - Memory allocation failed - cannot convert text\n");
+ warn(frontend, NULL, 0, "Memory allocation failed - cannot convert text");
return NULL;
}
nbytes=0;
@@ -235,7 +258,7 @@
newtext[nbytes++]=0;
break;
default:
- fprintf(stderr, "ERROR: encoding %d not handled in conversion!\n", encoding);
+ warn(frontend, NULL, 0, "encoding %d not handled in conversion!", encoding);
newtext = strdup("");
break;
}
@@ -252,7 +275,7 @@
#endif
-int load_subtitles(ff2theora_kate_stream *this, int ignore_non_utf8)
+int load_subtitles(ff2theora_kate_stream *this, int ignore_non_utf8, FILE *frontend)
{
#ifdef HAVE_KATE
enum { need_id, need_timing, need_text };
@@ -274,13 +297,13 @@
this->subtitles = NULL;
if (!this->filename) {
- fprintf(stderr,"WARNING - No subtitles file to load from\n");
+ warn(frontend, NULL, 0, "No subtitles file to load from");
return -1;
}
f = fopen(this->filename, "r");
if (!f) {
- fprintf(stderr,"WARNING - Failed to open subtitles file %s (%s)\n", this->filename, strerror(errno));
+ warn(frontend, NULL, 0, "Failed to open subtitles file %s (%s)", this->filename, strerror(errno));
return -1;
}
@@ -302,13 +325,13 @@
else {
ret=sscanf(str,"%d\n",&id);
if (ret!=1 || id<0) {
- fprintf(stderr,"WARNING - %s:%u: Syntax error: %s\n",this->filename,line,str);
+ warn(frontend, this->filename, line, "Syntax error: %s",str);
fclose(f);
free(this->subtitles);
return -1;
}
if (id!=last_seen_id+1) {
- fprintf(stderr,"WARNING - %s:%u: non consecutive ids: %s - pretending not to have noticed\n",this->filename,line,str);
+ warn(frontend, this->filename, line, "Non consecutive ids: %s - pretending not to have noticed",str);
}
last_seen_id=id;
need=need_timing;
@@ -318,7 +341,7 @@
case need_timing:
ret=sscanf(str,"%d:%d:%d%*[.,]%d --> %d:%d:%d%*[.,]%d\n",&h0,&m0,&s0,&ms0,&h1,&m1,&s1,&ms1);
if (ret!=8 || (h0|m0|s0|ms0)<0 || (h1|m1|s1|ms1)<0) {
- fprintf(stderr,"WARNING - %s:%u: Syntax error: %s\n",this->filename,line,str);
+ warn(frontend, this->filename, line, "Syntax error: %s",str);
fclose(f);
free(this->subtitles);
return -1;
@@ -335,8 +358,9 @@
remove_last_newline(text);
/* we want all text to be UTF8 */
- utf8=convert_subtitle_to_utf8(this->subtitles_encoding,text,ignore_non_utf8);
+ utf8=convert_subtitle_to_utf8(this->subtitles_encoding,text,ignore_non_utf8, frontend);
if (!utf8) {
+ warn(frontend, this->filename, line, "Failed to get UTF-8 text");
fclose(f);
free(this->subtitles);
return -1;
@@ -347,7 +371,7 @@
this->subtitles = (ff2theora_subtitle*)realloc(this->subtitles, (this->num_subtitles+1)*sizeof(ff2theora_subtitle));
if (!this->subtitles) {
free(utf8);
- fprintf(stderr, "Out of memory\n");
+ warn(frontend, NULL, 0, "Out of memory");
fclose(f);
free(this->subtitles);
return -1;
@@ -355,8 +379,9 @@
ret=kate_text_validate(kate_utf8,utf8,len+1);
if (ret<0) {
if (!warned) {
- fprintf(stderr,"WARNING - %s:%u: subtitle %s is not valid utf-8\n",this->filename,line,utf8);
- fprintf(stderr," further invalid subtitles will NOT be flagged\n");
+ warn(frontend, this->filename, line, "subtitle is not valid UTF-8: %s",utf8);
+ if (!frontend)
+ fprintf(stderr," further invalid subtitles will NOT be flagged\n");
warned=1;
}
}
@@ -377,7 +402,7 @@
/* in case of very long subtitles */
len=strlen(text);
if (len+strlen(str) >= sizeof(text)) {
- fprintf(stderr,"WARNING - %s:%u: subtitle text is too long - truncated\n",this->filename,line);
+ warn(frontend, this->filename, line, "Subtitle text is too long - truncated");
}
strncpy(text+len,str,sizeof(text)-len);
text[sizeof(text)-1]=0;
@@ -390,10 +415,13 @@
fclose(f);
+#if 0
+ // there seems to be quite a lot of files like this, so disable this test.
if (need!=need_id) {
/* shouldn't be a problem though, but warn */
- fprintf(stderr,"WARNING - %s:%u: missing data in %s - truncated file ?\n",this->filename,line,this->filename);
+ warn(frontend, this->filename, line, "Missing data in - truncated file ?");
}
+#endif
/* fprintf(stderr," %u subtitles loaded.\n", this->num_subtitles); */
@@ -403,7 +431,7 @@
#endif
}
-int add_subtitle_for_stream(ff2theora_kate_stream *streams, int nstreams, int idx, float t, float duration, const char *utf8, size_t utf8len)
+int add_subtitle_for_stream(ff2theora_kate_stream *streams, int nstreams, int idx, float t, float duration, const char *utf8, size_t utf8len, FILE *frontend)
{
#ifdef HAVE_KATE
int n, ret;
@@ -412,19 +440,19 @@
if (idx == ks->stream_index) {
ks->subtitles = (ff2theora_subtitle*)realloc(ks->subtitles, (ks->num_subtitles+1)*sizeof(ff2theora_subtitle));
if (!ks->subtitles) {
- fprintf(stderr, "Out of memory\n");
+ warn(frontend, NULL, 0, "Out of memory");
return -1;
}
ret=kate_text_validate(kate_utf8,utf8,utf8len);
if (ret<0) {
- fprintf(stderr,"WARNING - stream %d: subtitle %s is not valid UTF-8\n",idx,utf8);
+ warn(frontend, NULL, 0, "stream %d: subtitle %s is not valid UTF-8",idx,utf8);
}
else {
/* make a copy */
size_t len = utf8len;
char *utf8copy = (char*)malloc(utf8len);
if (!utf8copy) {
- fprintf(stderr, "Out of memory\n");
+ warn(frontend, NULL, 0, "Out of memory");
return -1;
}
memcpy(utf8copy, utf8, utf8len);
Modified: trunk/ffmpeg2theora/src/subtitles.h
===================================================================
--- trunk/ffmpeg2theora/src/subtitles.h 2009-07-25 22:52:38 UTC (rev 16335)
+++ trunk/ffmpeg2theora/src/subtitles.h 2009-07-26 07:33:08 UTC (rev 16336)
@@ -16,16 +16,16 @@
#define SUPPORTED_ENCODINGS "utf-8, utf8, iso-8859-1, latin1"
extern void add_kate_stream(ff2theora this);
-extern int load_subtitles(ff2theora_kate_stream *this, int ignore_non_utf8);
+extern int load_subtitles(ff2theora_kate_stream *this, int ignore_non_utf8, FILE *frontend);
extern void free_subtitles(ff2theora this);
extern void add_subtitles_stream(ff2theora this,int stream_index,const char *language,const char *category);
-extern int add_subtitle_for_stream(ff2theora_kate_stream *streams, int nstreams, int idx, float t, float duration, const char *utf8, size_t utf8len);
+extern int add_subtitle_for_stream(ff2theora_kate_stream *streams, int nstreams, int idx, float t, float duration, const char *utf8, size_t utf8len, FILE *frontend);
extern void set_subtitles_file(ff2theora this,const char *filename);
extern void set_subtitles_language(ff2theora this,const char *language);
extern void set_subtitles_category(ff2theora this,const char *category);
extern void set_subtitles_encoding(ff2theora this,F2T_ENCODING encoding);
-extern void report_unknown_subtitle_encoding(const char *name);
+extern void report_unknown_subtitle_encoding(const char *name, FILE *frontend);
#endif
Modified: trunk/ffmpeg2theora/src/theorautils.c
===================================================================
--- trunk/ffmpeg2theora/src/theorautils.c 2009-07-25 22:52:38 UTC (rev 16335)
+++ trunk/ffmpeg2theora/src/theorautils.c 2009-07-26 07:33:08 UTC (rev 16336)
@@ -152,7 +152,6 @@
*/
void add_fisbone_packet (oggmux_info *info) {
ogg_packet op;
- int n;
if (!info->audio_only) {
memset (&op, 0, sizeof (op));
@@ -211,6 +210,7 @@
#ifdef HAVE_KATE
if (info->with_kate) {
+ int n;
for (n=0; n<info->n_kate_streams; ++n) {
oggmux_kate_stream *ks=info->kate_streams+n;
memset (&op, 0, sizeof (op));
@@ -294,8 +294,8 @@
/* initialize kate if we have subtitles */
if (info->with_kate) {
+#ifdef HAVE_KATE
int ret, n;
-#ifdef HAVE_KATE
for (n=0; n<info->n_kate_streams; ++n) {
oggmux_kate_stream *ks=info->kate_streams+n;
ogg_stream_init (&ks->ko, rand ()); /* oops, add one ot the above */
Modified: trunk/ffmpeg2theora/subtitles.txt
===================================================================
--- trunk/ffmpeg2theora/subtitles.txt 2009-07-25 22:52:38 UTC (rev 16335)
+++ trunk/ffmpeg2theora/subtitles.txt 2009-07-26 07:33:08 UTC (rev 16336)
@@ -2,7 +2,7 @@
* Overview
* Subtitles related options
- * Converting non-utf-8 files to utf-8
+ * Converting non-UTF-8 files to UTF-8
* Examples
* Playing subtitles
@@ -11,9 +11,9 @@
* Overview
Subtitles are read from SubRip (.srt) format files and converted to
-Kate streams. Those SubRip files must be encoded in utf-8 (7 bit ASCII
-is a subset of utf-8 so is valid input as well). See below for more
-information on converting SubRip files with other encodings to utf-8.
+Kate streams. Those SubRip files must be encoded in UTF-8 (7 bit ASCII
+is a subset of UTF-8 so is valid input as well). See below for more
+information on converting SubRip files with other encodings to UTF-8.
Subtitles support requires libkate, available from:
http://code.google.com/p/libkate
@@ -36,7 +36,7 @@
* Subtitles related options
--subtitles <file>
- Loads subtitles from a file, which must be an utf-8 encoded SubRip
+ Loads subtitles from a file, which must be an UTF-8 encoded SubRip
(.srt) file
--subtitles-language <language>
@@ -57,19 +57,19 @@
--subtitles-encoding <encoding>
Sets the encoding of the relevant input file. Allowed encodings are
- utf-8, utf8, iso-8859-1, and latin1. The first two are synonymous and
+ UTF-8, UTF8, iso-8859-1, and latin1. The first two are synonymous and
yield no conversion. The latter two are synonymous and convert from
- iso-8859-1 to utf-8.
+ iso-8859-1 to UTF-8.
If the input file is in another encoding, a separate step is needed
- to convert the input file to utf-8. See below for more information on
- converting other encoding to utf-8.
- If unspecified, the default is utf-8.
+ to convert the input file to UTF-8. See below for more information on
+ converting other encoding to UTF-8.
+ If unspecified, the default is UTF-8.
--subtitles-ignore-non-utf8
- Any invalid sequence in utf-8 text will be ignored. This may be useful
- when using an utf-8 file with stray non utf-8 characters. This is not
- a substitute for converting a non utf-8 file to utf-8, however, as the
- non utf-8 sequence will be missing from the output stream.
+ Any invalid sequence in UTF-8 text will be ignored. This may be useful
+ when using an UTF-8 file with stray non UTF-8 characters. This is not
+ a substitute for converting a non UTF-8 file to UTF-8, however, as the
+ non UTF-8 sequence will be missing from the output stream.
--nosubtitles
Subtitle streams from the input file will not be converted. Subtitles
@@ -77,15 +77,15 @@
- * Converting non-utf-8 files to utf-8
+ * Converting non-UTF-8 files to UTF-8
-If you have SubRip files in another format than utf-8, you can use the
-iconv or recode programs to convert them to utf-8 so ffmpeg2theora can
+If you have SubRip files in another format than UTF-8, you can use the
+iconv or recode programs to convert them to UTF-8 so ffmpeg2theora can
read them.
* iconv
- If you have a file called subtitles.srt which is not in utf-8,
- you can convert it to utf-8 with the command:
+ If you have a file called subtitles.srt which is not in UTF-8,
+ you can convert it to UTF-8 with the command:
iconv -t utf-8 -f ENCODING subtitles.srt > subtitles.utf8.srt
@@ -95,18 +95,18 @@
encoding, replace ENCODING with UCS-2BE.
This will create a new file called subtitles.utf8.srt, which will
- be the equivalent of the input file, but in utf-8 format, so it
+ be the equivalent of the input file, but in UTF-8 format, so it
can be used as input to ffmpeg2theora.
- To view a list of all the encodings iconv can convert to utf-8,
+ To view a list of all the encodings iconv can convert to UTF-8,
see the output of `iconv -l'.
* recode
- If you have a file called subtitles.srt which is not in utf-8,
- you can convert it to utf-8 with the command:
+ If you have a file called subtitles.srt which is not in UTF-8,
+ you can convert it to UTF-8 with the command:
- recode ENCODING..utf-8 < subtitles.srt > subtitles.utf8.srt
+ recode ENCODING..UTF-8 < subtitles.srt > subtitles.utf8.srt
Substitute ENCODING with the actual encoding of the input file.
For instance, if your input file is in Shift-JIS encoding, replace
@@ -114,10 +114,10 @@
replace ENCODING with BIG5.
This will create a new file called subtitles.utf8.srt, which will
- be the equivalent of the input file, but in utf-8 format, so it
+ be the equivalent of the input file, but in UTF-8 format, so it
can be used as input to ffmpeg2theora.
- To view a list of all the encodings recode can convert to utf-8,
+ To view a list of all the encodings recode can convert to UTF-8,
see the output of `recode -l'.
@@ -148,5 +148,5 @@
At the moment, only VLC has playback support for Kate streams. However, the
libkate distribution includes patches for other players and media frameworks
-(MPlayer, GStreamer).
+(MPlayer, GStreamer, liboggplay).
More information about the commits
mailing list