[Risolto] Vedere e cancellare AVI in sequenza

Installazione, configurazione e utilizzo di applicativi multimediali, masterizzazione, acquisizione e codec audio/video, streaming e altro.
Avatar utente
corradoventu
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3815
Iscrizione: domenica 27 aprile 2008, 22:23
Desktop: GNOME
Distribuzione: Ubuntu 20.04, 22.04, 23.10, 24.04
Sesso: Maschile
Località: Rezzoaglio (GE)
Contatti:

[Risolto] Vedere e cancellare AVI in sequenza

Messaggio da corradoventu »

Ho alcune decine di AVI di pochi secondi ciascuno ripresi da una fototrappola. Vorrei conservarne alcuni (pochi) ed eliminare quelli non interessanti.
Se ne seleziono un gruppo con video (totem) posso saltare al prossimo con 'n' e quindi vederli in sequenza ma non trovo il modo di cancellare quello che sto vedendo, potete suggerirmi come fare? magari con una applicazione diversa da totem?
grazie
Ultima modifica di corradoventu il mercoledì 8 agosto 2018, 17:51, modificato 1 volta in totale.
Con o senza religione, i buoni si comportano bene e i cattivi male, ma ci vuole la religione per far comportare male i buoni.
(Steven Weinberg)
Avatar utente
dxgiusti
Rampante Reduce
Rampante Reduce
Messaggi: 5372
Iscrizione: lunedì 19 novembre 2007, 14:10
Desktop: Mate
Distribuzione: PCLinuxOS-Mate
Sesso: Maschile
Località: Lodi

Re: Vedere e cancellare AVI in sequenza

Messaggio da dxgiusti »

se per cancellarli intendi dal disco non credo che un lettore totem o altri ti diano quella possibilità. puoi certamente rimuoverli dalla scaletta di riproduzione
Avatar utente
corradoventu
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3815
Iscrizione: domenica 27 aprile 2008, 22:23
Desktop: GNOME
Distribuzione: Ubuntu 20.04, 22.04, 23.10, 24.04
Sesso: Maschile
Località: Rezzoaglio (GE)
Contatti:

Re: Vedere e cancellare AVI in sequenza

Messaggio da corradoventu »

vorrei cancellarli dal disco. ora ne seleziono e guardo 6 o 7 alla volta, mi ricordo quelli inutili e alla fine li cancello, ma è una cosa lunga, in due notti volpi e tassi sono passati 228 volte, e quindi ho 228 video di cui la maggior parte non significativi (solo occhi che brillano nell'infrarosso).
Con o senza religione, i buoni si comportano bene e i cattivi male, ma ci vuole la religione per far comportare male i buoni.
(Steven Weinberg)
Avatar utente
Stealth
Tenace Tecnocrate
Tenace Tecnocrate
Messaggi: 17342
Iscrizione: martedì 31 gennaio 2006, 22:55
Desktop: Gnome
Distribuzione: Ubuntu 22.04 LTS

Re: Vedere e cancellare AVI in sequenza

Messaggio da Stealth »

Soluzioni eleganti io non ne vedo e, a meno di voler implementare uno script apposito e per me complicato, torno ad essere un rozzo. Per cui io imposterei il salvataggio di tutti gli avi in una cartella temporanea. Dopo averli visti sposterei solo quelli che mi interessano nella loro directory definitiva e, a quel punto e in un colpo solo, selezioni e cancelli tutto il contenuto della directory
ciao
Avatar utente
giulux
Amministratore
Amministratore
Messaggi: 25422
Iscrizione: domenica 10 gennaio 2010, 12:17
Desktop: ubuntu 18.04
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Sesso: Maschile
Località: Roma

Re: Vedere e cancellare AVI in sequenza

Messaggio da giulux »

Forse dovresti rivolgerti a quelli di programmazione, per uno script che apra il primo video e chieda se vuoi cancellarlo: se no, passa al successivo (ed eventualmente lo sposta in una cartella 'file utili'), se si lo cancella e passa al seguente.
Questo come bruto schema di massima, quale può farlo uno come me che di programmazione e script non sa niente,
"Non è una segno di buona salute l'essere ben adattato ad una società malata". (Jiddu Krishnarmurti)
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: Vedere e cancellare AVI in sequenza

Messaggio da nuzzopippo »

giulux [url=https://forum.ubuntu-it.org/viewtopic.php?p=5073036#p5073036][img]https://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Forse dovresti rivolgerti a quelli di programmazione, per uno script che apra il primo video e chieda se vuoi cancellarlo: se no, passa al successivo (ed eventualmente lo sposta in una cartella 'file utili'), se si lo cancella e passa al seguente.
Questo come bruto schema di massima, quale può farlo uno come me che di programmazione e script non sa niente,
Mi ha intrigato :D Mai fatto niente del genere, ci ho provato con VLC e zenity : questo funziona secondo lo schema di @giuliux

Codice: Seleziona tutto

#!/bin/bash

# Utilizzo : vedi.sh dir_da_esaminare

#salvo le impostazioni IFS correnti ed adatto
currIFS=$IFS
IFS=$(echo -en "\n\b")

for file in $1/*
do
	vlc "$file" 2> /dev/null
	zenity --question --title="Cancellazione?"\
		--cancel-label="No" --ok-label="Cancella video"\
		--text="Cancello il video appena visto?" 2> /dev/null
	case $? in
		"-1"	)
			zenity --error --title="Errore imprevisto"\
				--text="Interrompo procedura" 2> /dev/null
			exit
			;;
		"0"	)
			rm "$file"
			;;
	esac
done
IFS=$currIFS
Richiede, ovviamente, vlc installato ed i files video in una directory da esaminare ... non fa alcuna verifica dei files, perciò predisporre i soli video da esaminare.

... magari serve, ciao :)
Fatti non foste a viver come bruti ...
Avatar utente
OMBRA_Linux
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2696
Iscrizione: mercoledì 18 febbraio 2015, 14:24
Desktop: HP / Lenovo / Samsung
Distribuzione: Android / Linux / Windows10-11
Sesso: Maschile
Località: Napoli

Re: Vedere e cancellare AVI in sequenza

Messaggio da OMBRA_Linux »

Secondo me sarebbe utile creare uno script che prima ti apre il video cosi vai a vedere un anteprima di quello che poi eventualmente vai a cancellare.
Detto questo uno script cosi a mio avviso è inutile ( In termini di tempo ) quindi per essere sicuro di quello che cancelli devi per forza aprirlo e poi decidere se eliminarlo oppure no.
Se per vivere devi strisciare, alzati e muori.
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: Vedere e cancellare AVI in sequenza

Messaggio da nuzzopippo »

OMBRA_Linux [url=https://forum.ubuntu-it.org/viewtopic.php?p=5073075#p5073075][img]https://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Secondo me sarebbe utile creare uno script che prima ti apre il video cosi vai a vedere un anteprima di quello che poi eventualmente vai a cancellare.
Detto questo uno script cosi a mio avviso è inutile ( In termini di tempo ) quindi per essere sicuro di quello che cancelli devi per forza aprirlo e poi decidere se eliminarlo oppure no.
beh ... in effetti è quello che fa : ti apre il video ed attende Tu chiuda vlc, quando lo chiudi ti chiede se lo vuoi cancellare o meno. Sul mio sistema funziona (provato su serie di 4 video), lo hai provato sul tuo? Funziona diversamente?

In merito alla lunghezza dello spezzone video, non è implementato ma potrebbe essere anche inserita la visualizzazione di un determinato intervallo ... richiederebbe una serie di operazioni di input che non sarebbero necessariamente conoscibili a priori.
Comunque è uno scriptino gettato li su due piedi e che presuppone la predisposizione di una direttrice (da passare come parametro) con dentro i files video da esaminare, potrebbe essere migliorato, sempre ammesso che lo OP ritenga possa essere utile.

[Edit] vedo ora, che ho lasciato le istruzioni di manipolazione dello IFS, le avevo inserite per una verifica tramite echo dei nomi di file precedente alla impostazione della visualizzazione/cancellazione, non sono necessarie per il funzionamento dello script corrente.
Fatti non foste a viver come bruti ...
Avatar utente
OMBRA_Linux
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 2696
Iscrizione: mercoledì 18 febbraio 2015, 14:24
Desktop: HP / Lenovo / Samsung
Distribuzione: Android / Linux / Windows10-11
Sesso: Maschile
Località: Napoli

Re: Vedere e cancellare AVI in sequenza

Messaggio da OMBRA_Linux »

Quello che intendevo dire io, visto che i video sono di pochi fotogrammi, è che creare uno script per eliminare quei video è inutile. Per me conviene aprirlo con qualsiasi programma video visionarlo e poi decidere di cancellarlo anche perchè ''Script o non Script'' si perde lo stesso tempo
Questo è un mio parere personale.
Se per vivere devi strisciare, alzati e muori.
Avatar utente
corradoventu
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 3815
Iscrizione: domenica 27 aprile 2008, 22:23
Desktop: GNOME
Distribuzione: Ubuntu 20.04, 22.04, 23.10, 24.04
Sesso: Maschile
Località: Rezzoaglio (GE)
Contatti:

Re: Vedere e cancellare AVI in sequenza

Messaggio da corradoventu »

grazie a tutti, proverò lo script.
edit: lo script è perfetto, grazie anche per zenity che non conoscevo.
con lo script mi risparmio di aprire i file uno per uno, me li apre lui.
Con o senza religione, i buoni si comportano bene e i cattivi male, ma ci vuole la religione per far comportare male i buoni.
(Steven Weinberg)
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da UbuNuovo »

Ciao Nuzzopippo, mi sono accorto che fa comodo anche a me.
Ho fatto alcune modifiche:
aggiunto un controllo sulla directory passata come argomento e sull'esistenza di file video
la possibilità di uscire dallo script prima della fine dei video
i file da scartare vengono spostati nel cestino, per recuperarli in caso di errore.
La ricerca è ricorsiva, viene fatta con find e vengono elencati solo i file video.

Per la scelta in zenity, fare doppio clic sulla voce voluta, oppure selezionarla e cliccare su Ok.

L'ho chiamato play_e_canc_video.sh

Codice: Seleziona tutto

#!/bin/bash
# UbuNuovo il 30 ottobre 2021
# deriva da quello scritto da nuzzopippo il 6 agosto 2018
# Descrizione: apre in sequenza video da una directory e chiede se cancellarli
# da https://forum.ubuntu-it.org/viewtopic.php?f=73&t=629670

# Utilizzo : play_e_canc_video.sh dir_da_esaminare

dir_video="$1"
if [ ! -d "$dir_video" ];then echo -e "Directory \"$dir_video\" \nPassare una directory valida!";exit;fi
el_video=$(find "$dir_video" -type f -print0 | xargs -0 file --mime-type 2>/dev/null | grep -E '\s+video/' | awk -F":" '{print $1}')
if [ -z "$el_video" ];then echo 'Non sono presenti file video, esco!';exit;fi

while read f;do
	vlc "$f" 2> /dev/null
	scelta=$(zenity --text="$f" --list --title="Operazione da eseguire sul file:" --column="0" "Continua" "Cestina" "Esci" --width=300 --height=200 --hide-header)
	echo "$scelta"
	case $scelta in
		"-1"	)
			zenity --error --title="Errore imprevisto"\
				--text="Interrompo procedura" 2> /dev/null
			exit
			;;
		"Cestina"	)
			# gvfs-trash "$f"
			gio trash "$f"
			;;
		"Continua"	)
			:
			;;
		"Esci"	)
			exit
			;;
	esac
done <<< "$el_video"

echo "Finito 8-)"
exit
Salva l'Ucraina! 🇺🇦
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da nuzzopippo »

Utili miglioramenti @UbuNuovo, molto interessante il riconoscimento di tipo del file, prima o poi dovrò trovare un po' di tempo per studiarmi awk
Fatti non foste a viver come bruti ...
Avatar utente
giulux
Amministratore
Amministratore
Messaggi: 25422
Iscrizione: domenica 10 gennaio 2010, 12:17
Desktop: ubuntu 18.04
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Sesso: Maschile
Località: Roma

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da giulux »

@UbuNuovo Ho copiato il tuo script, cambiandogli solo il nome e l'ho reso esecutivo, ho creato una directory di prova nella mia home mettendoci due filmati.
Al primo tentativo si è aperto vlc ma non zenity e ho chiuso brutalmente il terminale.
Nei successivi tentativi invece si apre zenity ma non vlc.
Il 'continua' e la cancellazione dei file funzionano, ma ovviamente posso agire solo 'al buio', cancellando il file il cui nome appare in zenity.

Codice: Seleziona tutto

giulux@ub20:~$ pl_canc.sh ~/provascript/
Continua
Continua
Finito 8-)
giulux@ub20:~$ pl_canc.sh ~/provascript/
Cestina
Cestina
Finito 8-)
giulux@ub20:
Dove sbaglio? Che devo fare'?
Grazie.

P.S. Tieni conto che di programmazione ne so meno che di turco.
"Non è una segno di buona salute l'essere ben adattato ad una società malata". (Jiddu Krishnarmurti)
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da UbuNuovo »

Il procedimento è questo:
Avvii lo script passando la directory da scandire come argomento (path assoluto o relativo)
si apre vlc con il primo video, lo guardi, quando hai deciso se cancellarlo o no, chiudi vlc
a questo punto si apre la finestra di zenity, fatta la scelta, zenity si chiude e parte vlc con il video successivo
e così via.
Zenity si apre solo dopo la chiusura di vlc.
Salva l'Ucraina! 🇺🇦
Avatar utente
giulux
Amministratore
Amministratore
Messaggi: 25422
Iscrizione: domenica 10 gennaio 2010, 12:17
Desktop: ubuntu 18.04
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Sesso: Maschile
Località: Roma

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da giulux »

OK, capito.
Grazie gobbo.
"Non è una segno di buona salute l'essere ben adattato ad una società malata". (Jiddu Krishnarmurti)
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da UbuNuovo »

Immagine
Salva l'Ucraina! 🇺🇦
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da UbuNuovo »

Ho trovato un altro modo. Esiste un'estensione apposita per VLC!
È uno script lua per VLC (vlc-delete.lua), cancella il file corrente dalla playlist e dal disco
https://github.com/surrim/vlc-delete/bl ... delete.lua

però non funzionava la parte di codice per spostare il file nel cestino!
Ho modificato quel codice e tradotto la voce di menù.

vlc-delete.lua (modificato)

Codice: Seleziona tutto

--[[
	Copyright 2015-2019 surrim
	This program 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.
	This program 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/>.
]]--

function descriptor()
	return {
		title = "VLC Delete";
		version = "0.1";
		author = "surrim";
		url = "https://github.com/surrim/vlc-delete/";
		shortdesc = "&Rimuove il file corrente dalla playlist e dal disco";
		description = [[
<h1>vlc-delete</h1>"
When you're playing a file, use VLC Delete to
delete the current file from your playlist and <b>disk</b> with one click.<br>
This extension has been tested on GNU Linux with VLC 2.1.5.<br>
The author is not responsible for damage caused by this extension.
		]];
	}
end

function fileExists(file)
	return io.popen("if exist " .. file .. " (echo 1)") : read "*l" == "1"
end

function sleep(seconds)
	local t0 = os.clock()
	local tOriginal = t0
	while os.clock() - t0 <= seconds and os.clock() >= tOriginal do end
end

function windowsDelete(file, trys, pause)
	if not fileExists("\"" .. file .. "\"") then return nil, "File does not exist" end
	for i = trys, 1, -1
	do
		retval, err = os.remove(file)
		--retval, err = os.execute("del " .. file )
		if retval == true then
			return true
		end
		sleep(pause)
	end
	return {nil, "Unable to delete file"}
end

function removeItem()
	local id = vlc.playlist.current()
	vlc.playlist.delete(id)
	vlc.playlist.gotoitem(id + 1)
	vlc.deactivate()
end

function activate()
	local item = vlc.input.item()
	local uri = item:uri()
	uri = string.gsub(uri, "^file:///", "")
	uri = vlc.strings.decode_uri(uri)
	vlc.msg.info("[vlc-delete] removing: " .. uri)

	if (package.config:sub(1, 1) == "/") then -- not windows
		-- retval, err = os.execute("trash-put --help > /dev/null")
		retval, err = os.execute("which gio > /dev/null")
		if (retval ~= nil) then
			uri = "/" .. uri
			-- retval, err = os.execute("trash-put \"" .. uri .. "\"")
			retval, err = os.execute("gio trash \"" .. uri .. "\"")
		else
			retval, err = os.execute("rm --help > /dev/null")
			if (retval ~= nil) then
				uri = "/" .. uri
				retval, err = os.execute("rm \"" .. uri .. "\"")
			end
		end
		if (retval ~= nil) then removeItem() end
	else -- windows
		removeItem() -- remove from playlist first so the file isnt locked by vlc
		uri = string.gsub(uri, "/", "\\")
		retval, err = windowsDelete(uri, 3, 1)
	end

	if (retval == nil) then
		vlc.msg.info("[vlc-delete] error: " .. err)
		d = vlc.dialog("VLC Delete")
		d:add_label("Could not remove \"" .. uri .. "\"", 1, 1, 1, 1)
		d:add_label(err, 1, 2, 1, 1)
		d:add_button("OK", click_ok, 1, 3, 1, 1)
		d:show()
	end
end

function click_ok()
	d:delete()
	vlc.deactivate()
end

function deactivate()
	vlc.deactivate()
end

function close()
	deactivate()
end

function meta_changed()
end
Per usare l'estensione
creare la directory ~/.local/share/vlc/lua/extensions

Codice: Seleziona tutto

mkdir -p "$HOME/.local/share/vlc/lua/extensions/"
copiarci lo scripit vlc-delete.lua (io ci ho messo un collegamento allo script) e riavviare VLC.
Per cancellare il video corrente, dal menù di VLC: Visualizza->Rimuove il file corrente dalla playlist e dal disco
oppure usare le scorciatoie: Alt+i seguito da Alt+r

È più utile dello script bash in caso di playlist o di video aperti "a mano"; va bene anche per più video aperti da terminale, per esempio:

Codice: Seleziona tutto

vlc video1.mp4 video2.mp4 video3.mp4
(oppure vlc *.mp4)
Ultima modifica di UbuNuovo il mercoledì 3 novembre 2021, 1:03, modificato 1 volta in totale.
Salva l'Ucraina! 🇺🇦
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da nuzzopippo »

UbuNuovo ha scritto:
lunedì 1 novembre 2021, 23:37
Ho trovato un altro modo. Esiste un'estensione apposita per VLC!
È uno script lua per VLC (vlc-delete.lua), cancella il file corrente dalla playlist e dal disco...
Come al solito, quando c6 il post diventa interessante :)

ho provato solo adesso la Tua variante bash, non avendo video sul computer casalingo (recentemente fritto da un fulmine) e devo dire che è veramente carina.

per l'ultimo lua = altro linguaggio da imparare ... comunque solletica ;)

Ciao
Fatti non foste a viver come bruti ...
Avatar utente
UbuNuovo
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4433
Iscrizione: sabato 12 dicembre 2009, 20:58
Desktop: Mate
Distribuzione: Ubuntu Mate 22.04.1 LTS
Sesso: Maschile
Contatti:

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da UbuNuovo »

Ho riguardato lo script LUA; la parte di controllo sull'esistenza del comando bash, basata su help, non va bene!
Ora correggo lo script usando which.

Codice: Seleziona tutto

...
		retval, err = os.execute("which gio > /dev/null")
		if (retval ~= nil) then
...
Salva l'Ucraina! 🇺🇦
Avatar utente
nuzzopippo
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1624
Iscrizione: giovedì 12 ottobre 2006, 11:34

Re: [Risolto] Vedere e cancellare AVI in sequenza

Messaggio da nuzzopippo »

Come accade spesso, @UbuNuovo mi ha intrigato ed ho provato a vedere cosa mi riusciva di combinare con python, tkinter e le librerie di VLC ... ed ho, quindi, impastato una piccola applicazione che oltre a far visualizzare e/o cancellare i video in una directori (come inizialmente chiesto da @corradovenu, "aspira" a voler essere un minimale "organizer" per file video. Nella figura sotto in azione mentre mi ascoltavo la lennox
Immagine
Mi ci son divertito ed a quanto ho testato sembra funzionare decentemente ed ho pensato di postare qui il codice nel caso a qualcuno possa interessare.
Nel caso esista qualche interessato, lo script richiede le librerie python-vlc e python-magic, suggerirei di installarle in un venv, questo è il "corredo" del venv in cui ha sviluppato e testato

Codice: Seleziona tutto

(vlc_v) NzP:~$ python -m pip list
Package       Version  
------------- ---------
pip           20.0.2   
pkg-resources 0.0.0    
python-magic  0.4.24   
python-vlc    3.0.12118
setuptools    44.0.0   
(vlc_v) NzP:~$ 
ed ora il codice (423 righe), lo ho chiamato vlcapp.py

Codice: Seleziona tutto

# -*- coding: utf-8 -*-

import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox as msgb
import vlc
import os
import magic
import time
import shutil


class ViewPanel(tk.Frame):
    '''Un pannello dedicato alla visualizzazione dei video'''
    def __init__(self, ctrl=True, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.video = ''
        self.started = False
        self.last_time = 0
        self.lbl_title = tk.Label(self, text='Nessun Video', justify='left')
        self.lbl_title.grid(row=0, column=0, sticky='ew')
        self.v_panel = tk.Canvas(self, bg='black')
        self.v_panel.grid(row=1, column=0, sticky='nsew')
        if ctrl:
            p_ctrl = tk.Frame(self)
            p_ctrl.grid(row=2, column=0, sticky='ew')
            bt_play = tk.Button(p_ctrl, font='Webdings',
                                text='\uF038\uF03B', command=self._on_play)
            bt_play.grid(row=0, column=0, sticky='s')
            bt_stop = tk.Button(p_ctrl, font='Webdings',
                                text='\uF03C', command=self._on_stop)
            bt_stop.grid(row=0, column=1, sticky='s')
            self.sc_time = tk.Scale(p_ctrl, from_=0, to=1000, orient=tk.HORIZONTAL,
                                    showvalue=0, command=self._on_time)
            self.sc_time.grid(row=0, column=2, sticky='ew')
            lbl = tk.Label(p_ctrl, font='Webdings', text='\uF056')
            lbl.grid(row=0, column=3, sticky='s')
            self.sc_vol = tk.Scale(p_ctrl, from_=0, to=100, orient=tk.HORIZONTAL, 
                                   showvalue=0, command=self._on_volume)
            #self.sc_vol.bind('<ButtonRelease-1>', self._on_time)
            self.sc_vol.grid(row=0, column=4, sticky='ew')
            p_ctrl.grid_columnconfigure(2, weight=1)
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(0, weight=1)
        # player vlc
        self.instance = vlc.Instance('--no-xlib')
        self.player = self.instance.media_player_new()
    
    def _on_play(self):
        if self.player.get_media():
            if self._pause:
                self.player.play()
            else:
                self.player.pause()
            self._pause = not self._pause

    def _play(self):
        if self.started: return
        if self.player.play():  # vlc da -1 se fallisce
            msgb.showWrror('Non riesco ad avviare il video.')
        else:
            time.sleep(5)
            self._pause = True
            t = self.player.get_length()
            if t > 0:
                self.sc_time.config(to=t)
            vol = self.player.audio_get_volume()
            self.sc_vol.set(vol)
            self.sc_vol.update()
            self.started = True
            self._on_tmpplay()

    def _on_stop(self):
        if self.player and self.started:
            self.player.pause()
            time.sleep(5)
            self.player.stop()
            self._pause = True
            self.started = False
            self.last_time = 0

    def _on_volume(self, evt=None):
        if self.player and self.started:
            vol = self.sc_vol.get()
            if self.player.audio_set_volume(vol):
                msgb.showerror('Aggiustamento volume fallito')

    def _on_time(self, evt=None):
        if not (self.player and self.started): return
        t = self.sc_time.get()
        if t != self.last_time:
            self.last_time = t
            self.player.set_time(t)

    def set_video(self, f_name):
        if not os.path.isfile(f_name): return
        self.video = str(f_name)
        media = self.instance.media_new(str(self.video))
        self.player.set_media(media)
        self.lbl_title.configure(text=os.path.basename(self.video))
        self.update()
        self.player.set_xwindow(self.v_panel.winfo_id())
        self._play()
    
    def close_video(self):
        if self.player and self.started:
            self.player.pause()
            time.sleep(5)
            self.player.stop()
            self._pause = True
            self.video = ''
            self.sc_time.set(0)
            self.sc_vol.set(0)
            self.started = False
    
    def _on_tmpplay(self):
        if not self.video: return
        if self.player:
            t = self.player.get_time()
            if t > 0:
                self.last_time = t
                self.sc_time.set(t)
                self.sc_time.update()
        self.after(1000, self._on_tmpplay)


class MyApp(tk.Tk):
    def __init__(self):
        self.is_play = False
        self.start_dir = os.path.expanduser('~')
        self.end_dir = ''
        self.sel_video = []
        super().__init__()
        self.title('Video Organizer')
        # controlli selezione video originali
        p_list = tk.Frame(self)
        p_list.grid(row=0, column=0, sticky='ns')
        lbl_f_o = tk.Label(p_list, text='Video originali', justify='left')
        lbl_f_o.grid(row=0, column=0, columnspan=3, padx=5, pady=5,sticky='ew')
        self.l_film = tk.Listbox(p_list)
        self.l_film.grid(row=1, column=0, columnspan=3, padx=5, pady=5, sticky='nsEW')
        self.b_play = tk.Button(p_list, text='Play', command=self._on_play)
        self.b_play.grid(row=2, column=0, padx=5, pady=5, sticky='nsew')
        self.b_stop = tk.Button(p_list, text='Stop', command=self._on_stop)
        self.b_stop.grid(row=2, column=1, padx=5, pady=5, sticky='nsew')
        self.b_del = tk.Button(p_list, text='Cancella', command=self._on_del)
        self.b_del.grid(row=2, column=2, padx=5, pady=5, sticky='nsew')
        p_list.grid_rowconfigure(1, weight=1)
        p_list.grid_columnconfigure(0, weight=1, uniform='a')
        p_list.grid_columnconfigure(1, weight=1, uniform='a')
        p_list.grid_columnconfigure(2, weight=1, uniform='a')
        # pannello video
        self.viewer = ViewPanel(self)
        self.viewer.grid(row=0, column=1, padx=5, pady=5, sticky='nsew')
        # controlli copia o spostamento video
        p_d_list = tk.Frame(self)
        p_d_list.grid(row=0, column=2, sticky='ns')
        lbl_f_d = tk.Label(p_d_list, text='Video da lavorare', justify='left')
        lbl_f_d.grid(row=0, column=0, columnspan=4, padx=5, pady=5,sticky='ew')
        self.l_d_film = tk.Listbox(p_d_list)
        self.l_d_film.grid(row=1, column=0, columnspan=4, padx=5, pady=5, sticky='nsew')
        self.b_copy = tk.Button(p_d_list, text='Copia', command=self._on_copy)
        self.b_copy.grid(row=2, column=0, padx=5, pady=5, sticky='nsew')
        self.b_move = tk.Button(p_d_list, text='Sposta', command=self._on_move)
        self.b_move.grid(row=2, column=1, padx=5, pady=5, sticky='nsew')
        self.b_nolist = tk.Button(p_d_list, text='Annulla', command=self._on_undo)
        self.b_nolist.grid(row=2, column=2, padx=5, pady=5, sticky='nsew')
        self.b_exec = tk.Button(p_d_list, text='Esegui', command=self._on_execute)
        self.b_exec.grid(row=2, column=3, padx=5, pady=5, sticky='nsew')
        p_d_list.grid_rowconfigure(1, weight=1)
        p_d_list.grid_columnconfigure(0, weight=1, uniform='b')
        p_d_list.grid_columnconfigure(1, weight=1, uniform='b')
        p_d_list.grid_columnconfigure(2, weight=1, uniform='b')
        p_d_list.grid_columnconfigure(3, weight=1, uniform='b')
        # comandi generali
        p_command = tk.Frame(self)
        p_command.grid(row=1, column=0, columnspan=3, sticky='ew')
        self.b_o_dir = tk.Button(p_command, text='Dir. origine', command=self._on_origin)
        self.b_o_dir.grid(row=0, column=0, padx=5, pady=5, sticky='ew')
        self.b_d_dir = tk.Button(p_command, text='Dir. destinazione', command=self._on_dest)
        self.b_d_dir.grid(row=0, column=1, padx=5, pady=5, sticky='ew')
        self.b_exit = tk.Button(p_command, text='Chiudi programma', command=self._on_exit)
        self.b_exit.grid(row=0, column=2, padx=5, pady=5, sticky='ew')
        p_command.grid_columnconfigure(0, weight=1, uniform='c')
        p_command.grid_columnconfigure(1, weight=1, uniform='c')
        p_command.grid_columnconfigure(2, weight=1, uniform='c')
        # report di sessione
        p_report = tk.Frame(self)
        p_report.grid(row=2, column=0, columnspan=3, padx=5, pady=5, sticky='nsew')
        self.t_rep = tk.Text(p_report, font='Courier 10', height=10, wrap='none', padx=5, pady=5)
        self.t_rep.grid(row=0, column=0, sticky='nsew')
        v_scroll = tk.Scrollbar(p_report, orient=tk.VERTICAL, command=self.t_rep.yview)
        v_scroll.grid(row=0, column=1, sticky='ns')
        self.t_rep.configure(yscrollcommand=v_scroll.set)
        p_report.rowconfigure(0, weight=1)
        p_report.columnconfigure(0, weight=1)

        self.grid_rowconfigure(0, weight=1)
        self.grid_columnconfigure(1, weight=1)

        self.update()
        l = self.winfo_reqwidth()
        h = self.winfo_reqheight()
        self.minsize(l, h)

        self._evaluate_self()

    def _on_play(self):
        indexes = self.l_film.curselection()
        if not indexes: return
        name = self.l_film.get(indexes[0])
        if not name: return
        if not self.start_dir: return
        f_name = os.path.join(self.start_dir, name)
        self.is_play = True
        self._evaluate_self()
        self.viewer.set_video(f_name)

    def _on_stop(self):
        self.viewer.close_video()
        self.is_play = False
        self._evaluate_self()

    def _on_del(self):
        indexes = self.l_film.curselection()
        if not indexes: return
        name = self.l_film.get(indexes[0])
        if not name: return
        try:
            os.unlink(os.path.join(self.start_dir, name))
        except OSError as e:
            msgb.showerror(repr(e))
            return
        msg = '\n\nCancellato file "%s" dalla directory origine.' % name
        self.t_rep.insert('end', msg)
        self._get_videos()
        self._evaluate_self()

    def _on_copy(self):
        indexes = self.l_film.curselection()
        if not indexes: return
        name = self.l_film.get(indexes[0])
        if not name: return
        if not self.end_dir: return
        tot_f = [f for f in os.listdir(self.end_dir) if
                 os.path.isfile(os.path.join(self.end_dir, f))]
        if name in tot_f:
            msgb.showerror(None, 'Video già esistente nella destinazione')
            return
        names = [x['name'] for x in self.sel_video]
        if name in names:
            msgb.showerror(None, 'Video già selezionato')
            return
        item = {}
        item['name'] = name
        item['action'] = 'copy'
        self.sel_video.append(item)
        self.l_d_film.insert('end', item['name'])
        self._evaluate_self()

    def _on_move(self):
        indexes = self.l_film.curselection()
        if not indexes: return
        name = self.l_film.get(indexes[0])
        if not name: return
        if not self.end_dir: return
        tot_f = [f for f in os.listdir(self.end_dir) if
                 os.path.isfile(os.path.join(self.end_dir, f))]
        if name in tot_f:
            msgb.showerror(None, 'Video già esistente nella destinazione')
            return
        names = [x['name'] for x in self.sel_video]
        if name in names:
            msgb.showerror(None, 'Video già selezionato')
            return
        item = {}
        item['name'] = name
        item['action'] = 'move'
        self.sel_video.append(item)
        self.l_d_film.insert('end', item['name'])
        self.l_d_film.itemconfigure(self.l_d_film.size() -1, fg='red')
        self._evaluate_self()

    def _on_undo(self):
        indexes = self.l_d_film.curselection()
        if not indexes: return
        index = indexes[0]
        self.l_d_film.delete(index)
        del(self.sel_video[index])
        self._evaluate_self()

    def _on_execute(self):
        self._copy_or_move_list()

    def _on_origin(self):
        d_o = filedialog.askdirectory(initialdir=self.start_dir)
        if d_o:
            if os.path.exists(d_o) and os.path.isdir(d_o):
                self.start_dir = d_o
                msg = '\nSelezionata directory di origine : %s' % self.start_dir
                self.t_rep.insert('end', msg)
                self._get_videos()

    def _on_dest(self):
        d_e = filedialog.askdirectory(initialdir=self.start_dir)
        if d_e:
            if os.path.exists(d_e) and os.path.isdir(d_e):
                self.end_dir = d_e
                msg = '\nSelezionata directory di destinazione : %s' % self.end_dir
                self.t_rep.insert('end', msg)
                self._get_dest_videos()
                self._verify_duples()

    def _on_exit(self):
        self.destroy()
    
    # ***************************
    # *** METODI DELLA CLASSE ***
    # ***************************

    def _evaluate_self(self):
        self.b_play.configure(state='disabled')
        self.b_stop.configure(state='disabled')
        self.b_del.configure(state='disabled')
        self.b_copy.configure(state='disabled')
        self.b_move.configure(state='disabled')
        self.b_nolist.configure(state='disabled')
        self.b_exec.configure(state='disabled')
        self.b_d_dir.configure(state='disabled')
        films_num = self.l_film.size()
        if films_num:
            if self.is_play:
                self.b_stop.configure(state='normal')
            else:
                self.b_play.configure(state='normal')
                self.b_del.configure(state='normal')
                self.b_copy.configure(state='normal')
                self.b_move.configure(state='normal')
                if not self.end_dir:
                    self.b_d_dir.configure(state='normal')
                films_num = self.l_d_film.size()
                if films_num:
                    self.b_nolist.configure(state='normal')
                    self.b_exec.configure(state='normal')
    
    def _get_videos(self):
        self.l_film.delete(0, 'end')
        tot_f = [f for f in os.listdir(self.start_dir) if
                 os.path.isfile(os.path.join(self.start_dir, f))]
        if not tot_f:
            msg = '\n - Nessun file video trovato'
            self.t_rep.insert('end', msg)
            return
        for f in tot_f:
            if 'video' in magic.from_file(os.path.join(self.start_dir, f), mime=True):
                self.l_film.insert('end', f)
                msg = '\n - Video : %s' % f
                self.t_rep.insert('end', msg)
        self._evaluate_self()
    
    def _get_dest_videos(self):
        tot_f = [f for f in os.listdir(self.end_dir) if
                 os.path.isfile(os.path.join(self.end_dir, f))]
        if not tot_f:
            msg = '\n - Nessun file trovato'
            self.t_rep.insert('end', msg)
            return
        count = 0
        for f in tot_f:
            if 'video' in magic.from_file(os.path.join(self.end_dir, f), mime=True):
                count += 1
        msg = '\n - presenti %d files di cui %d sono video' % (len(tot_f), count)
        self.t_rep.insert('end', msg)
        self._evaluate_self()
    
    def _verify_duples(self):
        tot_f = [f for f in os.listdir(self.end_dir) if
                 os.path.isfile(os.path.join(self.end_dir, f))]
        duplicate = 0
        for i in range(self.l_film.size()):
            name = self.l_film.get(i)
            if name in tot_f:
                self.l_film.itemconfigure(i, fg='violet')
                duplicate += 1
        if duplicate:
            msg = '\n - %d video della directory origine già presenti nella destinazione.' % duplicate
            self.t_rep.insert('end', msg)

    def _copy_or_move_list(self):
        msg = '\n\nESECUZIONE OPERAZIONI IMPOSTATE :'
        self.t_rep.insert('end', msg)
        try:
            for item in self.sel_video:
                f_or = os.path.join(self.start_dir, item['name'])
                f_dest = os.path.join(self.end_dir, item['name'])
                if item['action'] == 'copy':
                    shutil.copy(f_or, f_dest)
                    msg = '\n - copia di %s effettuata' % item['name']
                    self.t_rep.insert('end', msg)
                elif item['action'] == 'move':
                    shutil.move(f_or, f_dest)
                    msg = '\n - spostamento di %s effettuato' % item['name']
                else:
                    msgb.showerror('Errore nella applicazione: azione non valida')
                    return
        except OSError as e:
            msgb.showerror(repr(e))
            return
        msg = '\n\nSituazione di %s risultante:' % self.start_dir
        self.t_rep.insert('end', msg)
        self._get_videos()
        self._verify_duples()
        msg = '\n\nSituazione di %s risultante:' % self.end_dir
        self.t_rep.insert('end', msg)
        self._get_dest_videos()
        self.l_d_film.delete(0, 'end')
        self.sel_video = []



if __name__ == '__main__':
    app = MyApp()
    app.mainloop()
N.B. : se lo si esegue in terminale possono apparire dei messaggi del server VLC mentre si visualizzano alcuni tipi di video o si sposta il cursore temporale all'indietro

Codice: Seleziona tutto

(vlc_v) NzP:~$ /home/nuzzopippo/pyvenvs/vlc_v/bin/python3 /media/nuzzopippo/1FA6-C648/src/vlc/prova_01/vclapp.py
[00007f6a2400c4c0] main filter error: Failed to create video converter
[00007f6a4c0586c0] vdpau_avcodec generic error: Xlib is required for VDPAU
[00007f6a5002ada0] main decoder error: Timestamp conversion failed (delay 1000000, buffering 100000, bound 9000000)
[00007f6a5002ada0] main decoder error: Could not convert timestamp 12984808943 for FFmpeg
[00007f6a50072f00] main decoder error: Timestamp conversion failed (delay 1000000, buffering 0, bound 3000000)
[00007f6a50072f00] main decoder error: Could not convert timestamp 12982485876 for mpg123
...
Non mi è riuscito di interagire con la libreria in modo tale da evitare tali messaggi ma non sembrano inficiare le funzionalità di visualizzazione.

Ovvio, lo ho testato per quanto mi è venuto in mente e sembra andar bene ma qualcosa magari mi è sfuggito, nel caso me ne accorga in seguito segnalerò e correggerò il codice ... potrebbe anche essere "migliorata" se a qualcuno venisse un qualche suggerimento.

[Edit] Dimenticavo, il codice è specifico per linux, NON funzionerebbe in windows o sui mac.

Ciao :)
Fatti non foste a viver come bruti ...
Scrivi risposta

Ritorna a “Multimediale”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 8 ospiti