Now fills the original info for a movie file

Now detects if a file is not a video file and shows an error

Now the interface_manager class can manage treelists
This commit is contained in:
Sergio Costas 2014-07-17 21:23:28 +02:00
parent d59fc7c0e7
commit 581cf07458
10 changed files with 391 additions and 230 deletions

View file

@ -22,7 +22,14 @@
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkListStore" id="liststore_subs">
<object class="GtkAdjustment" id="subt_font_size">
<property name="lower">10</property>
<property name="upper">50</property>
<property name="value">10</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkListStore" id="subtitles_list">
<columns>
<!-- column-name Subtitles file -->
<column type="gchararray"/>
@ -32,13 +39,6 @@
<column type="gchararray"/>
</columns>
</object>
<object class="GtkAdjustment" id="subt_font_size">
<property name="lower">10</property>
<property name="upper">50</property>
<property name="value">10</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="video_rate">
<property name="lower">400</property>
<property name="upper">8500</property>
@ -223,6 +223,8 @@
<object class="GtkLabel" id="label5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">baseline</property>
<property name="margin_left">8</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Original video rate (Kbits/sec):</property>
</object>
@ -264,6 +266,7 @@
<object class="GtkLabel" id="label8">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">8</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Original audio rate (Kbits/sec):</property>
</object>
@ -305,6 +308,7 @@
<object class="GtkLabel" id="label9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">8</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Original aspect ratio:</property>
</object>
@ -319,6 +323,7 @@
<object class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_left">8</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Frames per second:</property>
</object>
@ -808,7 +813,7 @@
<object class="GtkTreeView" id="treeview_subtitles">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore_subs</property>
<property name="model">subtitles_list</property>
<property name="headers_clickable">False</property>
<property name="enable_search">False</property>
<child internal-child="selection">
@ -894,12 +899,13 @@
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button_add_subtitles">
<object class="GtkButton" id="add_subtitles">
<property name="label">gtk-add</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_add_subtitles_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
@ -908,12 +914,13 @@
</packing>
</child>
<child>
<object class="GtkButton" id="button_del_subtitles">
<object class="GtkButton" id="del_subtitles">
<property name="label">gtk-delete</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="on_del_subtitles_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>

116
data/interface/wmessage.ui Normal file
View file

@ -0,0 +1,116 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkListStore" id="liststore_elements">
<columns>
<!-- column-name elements -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="dialog_message">
<property name="width_request">480</property>
<property name="height_request">360</property>
<property name="can_focus">False</property>
<property name="modal">True</property>
<property name="window_position">center</property>
<property name="type_hint">dialog</property>
<property name="deletable">False</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox1">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area1">
<property name="can_focus">False</property>
<property name="layout_style">center</property>
<child>
<object class="GtkButton" id="button1">
<property name="label">gtk-ok</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="label_message">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow" id="list_message">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="treeview1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">liststore_elements</property>
<property name="headers_visible">False</property>
<property name="enable_search">False</property>
<property name="show_expanders">False</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="treeview-selection1"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="treeviewcolumn1">
<property name="title" translatable="yes">column</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext1"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">button1</action-widget>
</action-widgets>
</object>
</interface>

View file

@ -1,48 +0,0 @@
#!/usr/bin/env python3
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import subprocess
import devede.configuration_data
class check_binaries:
def __init__(self):
self.config = devede.configuration_data.configuration.get_config()
self.check_mplayer()
self.check_mpv()
def check_mplayer(self):
handle = subprocess.Popen(["mplayer","-v"])
if 0==handle.wait():
self.config.mplayer_available = True
else:
self.config.mplayer_available = False
def check_mpv(self):
handle = subprocess.Popen(["mpv","-v"])
if 0==handle.wait():
self.config.mpv_available = True
else:
self.config.mpv_available = False

View file

@ -16,7 +16,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>
import devede.configuration_data
import devede.mpv_converter
import devede.mplayer_detector
class converter:
@ -32,7 +32,7 @@ class converter:
def __init__(self):
self.config = devede.configuration_data.configuration.get_config()
self.c = [devede.mpv_converter.mpv_converter]
self.c = [devede.mplayer_detector.mplayer_detector]
self.analizers = {}
self.default_analizer = None
@ -44,23 +44,22 @@ class converter:
self.default_menuer = None
for element in self.c:
e = element()
if (e.check_is_installed() == False):
if (element.check_is_installed() == False):
continue
name = e.display_name
if (e.supports_analize):
name = element.display_name
if (element.supports_analize):
self.analizers[name] = element
if (self.default_analizer == None):
self.default_analizer = element
if (e.supports_play):
if (element.supports_play):
self.players[name] = element
if (self.default_player == None):
self.default_player = element
if (e.supports_convert):
if (element.supports_convert):
self.converters[name] = element
if (self.default_converter == None):
self.default_converter = element
if (e.supports_menu):
if (element.supports_menu):
self.menuers[name] = element
if (self.default_menuer == None):
self.default_menuer = element
@ -71,8 +70,7 @@ class converter:
programs that covers the needs for that group; when not, it contains the programs valid
to cover the needs for that group.
The groups are, in this order: ANALIZERS, PLAYERS, CONVERTERS, MENUERS
(menuers are the programs that creates the mpeg files for menus)
"""
(menuers are the programs that creates the mpeg files for menus) """
if (self.default_analizer != None):
analizers = None

View file

@ -84,6 +84,8 @@ class file_movie(devede.interface_manager.interface_manager):
self.add_integer_adjustment("subt_font_size", 28)
self.add_float_adjustment("audio_delay", 0.0)
self.add_list("subtitles_list")
self.add_show_hide("format_pal", ["size_pal"], ["size_ntsc"])
self.add_enable_disable("divide_in_chapters", ["chapter_size_spinbutton"], [])
@ -104,21 +106,22 @@ class file_movie(devede.interface_manager.interface_manager):
is_mpeg_ps_list.append("no_reencode_audio_video")
is_mpeg_ps_list.append("font_size_spinbutton")
is_mpeg_ps_list.append("force_subtitles")
is_mpeg_ps_list.append("button_add_subtitles")
is_mpeg_ps_list.append("button_del_subtitles")
is_mpeg_ps_list.append("add_subtitles")
is_mpeg_ps_list.append("del_subtitles")
no_reencode_audio_video_list = common_elements[:]
no_reencode_audio_video_list.append("is_mpeg_ps")
self.add_enable_disable("is_mpeg_ps", [], is_mpeg_ps_list)
self.add_enable_disable("no_reencode_audio_video", [], no_reencode_audio_video_list)
#self.add_enable_disable("", [], [])
cv = devede.converter.converter()
film_analizer = (cv.get_film_analizer())()
if (film_analizer.get_film_data(self)):
self.error = True
else:
self.error = False
#cv = devede.converter.converter()
#cv.get_film_data(self)
def set_type(self,obj = None,disc_type = None):
if (disc_type != None):

View file

@ -24,14 +24,15 @@ class interface_manager(GObject.GObject):
def __init__(self):
self.groups = {}
self.toggles = []
self.labels = []
self.text = []
self.show_hide = []
self.enable_disable = []
self.float_adjustments = []
self.integer_adjustments = []
self.interface_groups = {}
self.interface_toggles = []
self.interface_labels = []
self.interface_text = []
self.interface_show_hide = []
self.interface_enable_disable = []
self.interface_float_adjustments = []
self.interface_integer_adjustments = []
self.interface_lists = []
def add_group(self,group_name,radiobutton_list,default_value):
""" Adds a group of radiobuttons and creates an internal variable with
@ -43,7 +44,7 @@ class interface_manager(GObject.GObject):
exec('self.'+group_name+' = "'+str(default_value)+'"')
else:
exec('self.'+group_name+' = None')
self.groups[group_name] = radiobutton_list
self.interface_groups[group_name] = radiobutton_list
def add_toggle(self,toggle_name,default_value):
""" Adds an internal variable with the name toggle_name, linked to a widget
@ -51,7 +52,7 @@ class interface_manager(GObject.GObject):
The default value can be True of False """
exec('self.'+toggle_name+' = '+str(default_value))
self.toggles.append(toggle_name)
self.interface_toggles.append(toggle_name)
def add_text(self,text_name,default_value):
""" Adds an internal variable with the name text_name, linked to an
@ -62,7 +63,7 @@ class interface_manager(GObject.GObject):
exec('self.'+text_name+' = "'+str(default_value)+'"')
else:
exec('self.'+text_name+' = None')
self.text.append(text_name)
self.interface_text.append(text_name)
def add_label(self,text_name,default_value):
""" Adds an internal variable with the name text_name, linked to an
@ -71,7 +72,7 @@ class interface_manager(GObject.GObject):
but is never updated from the UI if the user changes it """
exec('self.'+text_name+' = default_value')
self.labels.append(text_name)
self.interface_labels.append(text_name)
def add_integer_adjustment(self,adjustment_name,default_value):
""" Adds an internal variable with the name text_name, linked to an
@ -79,7 +80,7 @@ class interface_manager(GObject.GObject):
The default value must be an integer """
exec('self.'+adjustment_name+' = '+str(default_value))
self.integer_adjustments.append(adjustment_name)
self.interface_integer_adjustments.append(adjustment_name)
def add_float_adjustment(self,adjustment_name,default_value):
""" Adds an internal variable with the name text_name, linked to an
@ -87,8 +88,12 @@ class interface_manager(GObject.GObject):
The default value must be an float """
exec('self.'+adjustment_name+' = '+str(default_value))
self.float_adjustments.append(adjustment_name)
self.interface_float_adjustments.append(adjustment_name)
def add_list(self,liststore_name):
exec('self.'+liststore_name+' = []')
self.interface_lists.append(liststore_name)
def add_show_hide(self,element_name,to_show,to_hide):
""" Adds an element that can be active or inactive, and two lists of elements.
@ -97,7 +102,7 @@ class interface_manager(GObject.GObject):
elements that will be visible when the element is inactive, and
invisible when the element is active """
self.show_hide.append([element_name, to_show, to_hide])
self.interface_show_hide.append([element_name, to_show, to_hide])
def add_enable_disable(self,element_name,to_enable,to_disable):
""" Adds an element that can be active or inactive, and two lists of elements.
@ -106,43 +111,50 @@ class interface_manager(GObject.GObject):
elements that will be enabled when the element is inactive, and
disabled when the element is active """
self.enable_disable.append([element_name, to_enable, to_disable])
self.interface_enable_disable.append([element_name, to_enable, to_disable])
def update_ui(self,builder):
""" Sets the value of the widgets in base of the internal variables """
for key in self.groups:
for key in self.interface_groups:
obj = eval('self.'+key)
builder.get_object(obj).set_active(True)
for element in self.toggles:
for element in self.interface_toggles:
value = eval('self.'+element)
builder.get_object(element).set_active(value)
for element in self.text:
for element in self.interface_text:
value = eval('self.'+element)
if (value != None):
builder.get_object(element).set_text(value)
else:
builder.get_object(element).set_text("")
for element in self.labels:
for element in self.interface_labels:
value = eval('self.'+element)
if (value != None):
builder.get_object(element).set_text(str(value))
else:
builder.get_object(element).set_text("")
for element in self.integer_adjustments:
for element in self.interface_integer_adjustments:
value = eval('self.'+element)
builder.get_object(element).set_value(float(value))
for element in self.float_adjustments:
for element in self.interface_float_adjustments:
value = eval('self.'+element)
builder.get_object(element).set_value(value)
self.show_hide_obj = {}
for element in self.show_hide:
for element in self.interface_lists:
obj = eval('self.'+element)
the_liststore = builder.get_object(element)
the_liststore.clear()
for item in obj:
the_liststore.append(item)
self.interface_show_hide_obj = {}
for element in self.interface_show_hide:
obj = builder.get_object(element[0])
to_show = []
for e2 in element[1]:
@ -150,12 +162,12 @@ class interface_manager(GObject.GObject):
to_hide = []
for e3 in element[2]:
to_hide.append(builder.get_object(e3))
self.show_hide_obj[obj] = [to_show, to_hide]
self.interface_show_hide_obj[obj] = [to_show, to_hide]
obj.connect('toggled',self.toggled_element)
self.toggled_element(obj)
self.enable_disable_obj = {}
for element in self.enable_disable:
self.interface_enable_disable_obj = {}
for element in self.interface_enable_disable:
obj = builder.get_object(element[0])
to_enable = []
for e2 in element[1]:
@ -163,7 +175,7 @@ class interface_manager(GObject.GObject):
to_disable = []
for e3 in element[2]:
to_disable.append(builder.get_object(e3))
self.enable_disable_obj[obj] = [to_enable, to_disable]
self.interface_enable_disable_obj[obj] = [to_enable, to_disable]
obj.connect('toggled',self.toggled_element2)
self.toggled_element2(obj)
@ -171,9 +183,9 @@ class interface_manager(GObject.GObject):
""" Wenever an element with 'hide' or 'show' needs is toggled, this callback is called """
# First, show all items for each possible element
for key in self.show_hide_obj:
to_show = self.show_hide_obj[key][0]
to_hide = self.show_hide_obj[key][1]
for key in self.interface_show_hide_obj:
to_show = self.interface_show_hide_obj[key][0]
to_hide = self.interface_show_hide_obj[key][1]
active = key.get_active()
@ -188,9 +200,9 @@ class interface_manager(GObject.GObject):
# And now, hide all items that must be hiden
# This is done this way because this allows to have an item being hiden by
# one widget, and being shown by another: in that case, it will be hiden always
for key in self.show_hide_obj:
to_show = self.show_hide_obj[key][0]
to_hide = self.show_hide_obj[key][1]
for key in self.interface_show_hide_obj:
to_show = self.interface_show_hide_obj[key][0]
to_hide = self.interface_show_hide_obj[key][1]
active = key.get_active()
@ -207,9 +219,9 @@ class interface_manager(GObject.GObject):
""" Wenever an element with 'enable' or 'disable' needs is toggled, this callback is called """
# First enable all items that must be enabled
for key in self.enable_disable_obj:
to_enable = self.enable_disable_obj[key][0]
to_disable = self.enable_disable_obj[key][1]
for key in self.interface_enable_disable_obj:
to_enable = self.interface_enable_disable_obj[key][0]
to_disable = self.interface_enable_disable_obj[key][1]
active = key.get_active()
if (active):
@ -222,9 +234,9 @@ class interface_manager(GObject.GObject):
# And now, disable all items that must be disabled
# This is done this way because this allows to have an item being disabled by
# one widget, and being enabled by another: in that case, it will be disabled always
for key in self.enable_disable_obj:
to_enable = self.enable_disable_obj[key][0]
to_disable = self.enable_disable_obj[key][1]
for key in self.interface_enable_disable_obj:
to_enable = self.interface_enable_disable_obj[key][0]
to_disable = self.interface_enable_disable_obj[key][1]
active = key.get_active()
if (not active):
@ -237,30 +249,35 @@ class interface_manager(GObject.GObject):
def store_ui(self,builder):
""" Takes the values of the widgets and stores them in the internal variables """
for key in self.groups:
for element in self.groups[key]:
for key in self.interface_groups:
for element in self.interface_groups[key]:
obj = builder.get_object(element)
if obj.get_active():
exec('self.'+key+' = "'+element+'"')
break
for element in self.toggles:
for element in self.interface_toggles:
obj = builder.get_object(element)
if obj.get_active():
exec('self.'+element+' = True')
else:
exec('self.'+element+' = False')
for element in self.text:
for element in self.interface_text:
obj = builder.get_object(element)
exec('self.'+element+' = obj.get_text()')
for element in self.integer_adjustments:
for element in self.interface_integer_adjustments:
obj = builder.get_object(element)
exec('self.'+element+' = int(obj.get_value())')
for element in self.float_adjustments:
for element in self.interface_float_adjustments:
obj = builder.get_object(element)
exec('self.'+element+' = obj.get_value()')
for element in self.interface_lists:
exec('self.'+element+' = []')
the_liststore = builder.get_object(element)
for row in the_liststore:
exec('self.'+element+'.append(row.model[row.iter])')

47
src/devede/message.py Normal file
View file

@ -0,0 +1,47 @@
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
from gi.repository import Gtk
import os
import devede.configuration_data
class message_window:
def __init__(self,text,title,list_data = None):
self.config = devede.configuration_data.configuration.get_config()
builder = Gtk.Builder()
builder.set_translation_domain(self.config.gettext_domain)
builder.add_from_file(os.path.join(self.config.glade,"wmessage.ui"))
builder.connect_signals(self)
wmessage_window = builder.get_object("dialog_message")
wmessage_window.set_title(title)
wmessage_text = builder.get_object("label_message")
wmessage_text.set_markup(text)
wmessage_list = builder.get_object("list_message")
wmessage_liststore = builder.get_object("liststore_elements")
if (list_data == None):
wmessage_list.hide()
else:
for element in list_data:
wmessage_liststore.append([element])
wmessage_window.show_all()
wmessage_window.run()
wmessage_window.destroy()

View file

@ -0,0 +1,119 @@
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import subprocess
import devede.configuration_data
class mplayer_detector:
supports_analize = True
supports_play = True
supports_convert = False
supports_menu = False
display_name = "MPLAYER"
@staticmethod
def check_is_installed():
handle = subprocess.Popen(["mplayer","-v"], stdout = subprocess.PIPE, stderr = subprocess.PIPE)
(stdout, stderr) = handle.communicate()
if 0==handle.wait():
return True
else:
return False
def __init__(self):
self.config = devede.configuration_data.configuration.get_config()
def get_film_data(self,movie):
""" processes a file, refered by the FILE_MOVIE movie object, and fills its
main data (resolution, FPS, length...) """
video = self.get_film_data2(movie, True)
if (video):
self.get_film_data2(movie, False)
return False # no error
else:
return True # the file is not a video file; maybe an audio-only file, or another thing
def get_film_data2(self,movie,check_audio):
if (check_audio):
frames = "0"
else:
frames = "1"
command_line = ["mplayer","-loop","1","-identify", "-vo", "null", "-ao", "null", "-frames", frames , movie.file_name]
handle = subprocess.Popen(command_line, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
(stdout, stderr) = handle.communicate()
minimum_audio=-1
movie.audio_list=[]
movie.audio_streams = 0
movie.video_streams = 0
movie.original_width = 0
movie.original_height = 0
for line in str(stdout).split("\\n"):
#line=self.remove_ansi(line)
if line == "":
continue
position=line.find("ID_")
if position==-1:
continue
line=line[position:]
if (not check_audio):
if line[:16]=="ID_VIDEO_BITRATE":
movie.original_videorate=int(int(line[17:])/1000)
if line[:14]=="ID_VIDEO_WIDTH":
movie.original_width=int(line[15:])
if line[:15]=="ID_VIDEO_HEIGHT":
movie.original_height=int(line[16:])
if line[:15]=="ID_VIDEO_ASPECT":
movie.original_aspect_ratio=float(line[16:])
if line[:12]=="ID_VIDEO_FPS":
movie.original_fps=float(line[13:])
if line[:16]=="ID_AUDIO_BITRATE":
movie.original_audiorate=int(int(line[17:])/1000)
if line[:13]=="ID_AUDIO_RATE":
movie.original_audiorate_uncompressed=int(line[14:])
if line[:9]=="ID_LENGTH":
movie.original_length=int(float(line[10:]))
if line[:11]=="ID_VIDEO_ID":
movie.video_streams+=1
if line[:11]=="ID_AUDIO_ID":
movie.audio_streams+=1
audio_track=int(line[12:])
if (minimum_audio == -1) or (minimum_audio>audio_track):
minimum_audio=audio_track
movie.audio_list.append(audio_track)
movie.original_size = str(movie.original_width)+"x"+str(movie.original_height)
if (movie.original_aspect_ratio == None) or (movie.original_aspect_ratio <= 1.0):
if (movie.original_height != 0):
movie.original_aspect_ratio = (float(movie.original_width))/(float(movie.original_height))
if (movie.original_aspect_ratio != None):
movie.original_aspect_ratio = (float(int(movie.original_aspect_ratio*1000.0)))/1000.0
if (movie.video_streams == 0):
return False
else:
return True

View file

@ -1,105 +0,0 @@
# Copyright 2014 (C) Raster Software Vigo (Sergio Costas)
#
# This file is part of DeVeDe-NG
#
# DeVeDe-NG is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DeVeDe-NG is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>
import subprocess
import devede.configuration_data
class mpv_converter:
def __init__(self):
self.config = devede.configuration_data.configuration.get_config()
self.supports_analize = True
self.supports_play = True
self.supports_convert = False
self.supports_menu = False
self.display_name = "MPV"
def check_is_installed(self):
handle = subprocess.Popen(["mpv","-v"])
if 0==handle.wait():
return True
else:
return False
def get_film_data(self,movie):
""" processes a file, refered by the FILE_MOVIE movie object, and fills its
main data (resolution, FPS, length...) """
def get_film_data2(self,movie,check_audio):
if (check_audio):
frames = "0"
else:
frames = "1"
if self.config.mpv_available:
command_line = ["mpv","identify","-loop","1","-identify", "-ao", "null", "-vo", "null", "-frames", "1"]
else:
command_line = ["mplayer","identify","-loop","1","-identify", "-ao", "null", "-vo", "null", "-frames", "1"]
command_line.append(movie.file_name)
handle = subprocess.Popen(command_line)
(stdout, stderr) = handle.communicate()
minimum_audio=-1
audio_list=[]
audio = 0
video = 0
for line in stdout:
line=self.remove_ansi(line)
if line == "":
continue
position=line.find("ID_")
if position==-1:
continue
line=line[position:]
if line[:16]=="ID_VIDEO_BITRATE":
vrate=int(line[17:])
if line[:14]=="ID_VIDEO_WIDTH":
width=int(line[15:])
if line[:15]=="ID_VIDEO_HEIGHT":
height=int(line[16:])
if line[:15]=="ID_VIDEO_ASPECT":
aspect_ratio=float(line[16:])
if line[:12]=="ID_VIDEO_FPS":
fps2=line[13:]
while ord(fps2[-1])<32:
fps2=fps2[:-1]
posic=line.find(".")
if posic==-1:
fps=int(line[13:])
else:
fps=int(line[13:posic])
if line[posic+1]=="9":
fps+=1
if line[:16]=="ID_AUDIO_BITRATE":
arate=int(line[17:])
if line[:13]=="ID_AUDIO_RATE":
audiorate=int(line[14:])
if line[:9]=="ID_LENGTH":
length=int(float(line[10:]))
if line[:11]=="ID_VIDEO_ID":
video+=1
if line[:11]=="ID_AUDIO_ID":
audio+=1
audio_track=int(line[12:])
if (minimum_audio == -1) or (minimum_audio>audio_track):
minimum_audio=audio_track
audio_list.append(audio_track)

View file

@ -21,6 +21,7 @@ import os
import devede.file_movie
import devede.ask
import devede.add_files
import devede.message
class devede_project:
@ -156,12 +157,18 @@ class devede_project:
def on_add_file_clicked(self,b):
error_list = []
ask_files = devede.add_files.add_files()
if (ask_files.run()):
for efile in ask_files.files:
new_file = devede.file_movie.file_movie(efile)
if (new_file.error):
error_list.append(os.path.basename(efile))
else:
new_file.connect('title_changed',self.title_changed)
self.wliststore_files.append([new_file, new_file.title_name])
if (len(error_list)!=0):
devede.message.message_window(_("The following files could not be added:"),_("Error while adding files"),error_list)
self.set_interface_status(None)