Piero V.

Download video in streaming flash con Python

Un tempo su Linux si poteva trovare un video guardato in streaming direttamente nella directory /tmp.

In seguito, con degli aggiornamenti, flash scaricava il video sempre lì, ma veniva eliminato, anche se fisicamente presente.

Per ritrovarlo bastava trovare il processo dell’implementazione flash del browser, solitamente con ps aux | grep flash e così si trovavano i possibili pid.

Andando a vedere nella directory /proc/pid/fd, si trovavano tanti link, uno di questi a un file tipo /tmp/Flash.... In seguito si poteva trattare quel link come se fosse un file normale, quindi riprodurlo, passarlo a mencoder o ffmpeg etc… Se volevate copiarlo dovevate aspettare che il browser avesse finito di scaricare il video!

In seguito sembrava essere scomparsa anche questa possibilità, ma oggi mi sono accorto che è tornata, quindi vi lascio un breve file in python che permette di trovare automaticamente i vari file:

#!/usr/bin/env python
import os

for pid in os.listdir('/proc'):
	if not pid.isdigit():
		continue

	fdpath = '/proc/' + str(pid) + '/fd'
	try:
		fd = os.listdir(fdpath)
	except:
		continue

	for fid in fd:
		try:
			# Not a link? Raise exception
			fname = os.readlink(fdpath + '/' + fid)
			fname = fname.strip()

			if fname.lower().find('/tmp/flash') == 0:
				fname = fname.split(' ')[0]
				print fdpath + '/' + fid + ' => ' + fname

		except:
			continue

Questo script è stato scritto molto velocemente: cerca di andare in tutti i pid e di trovare i vari link. Se contengono la parola flash stampa il link e la destinazione. So che si potrebbe fare una cosa migliore ma in questo caso preferisco fare lo script kid 😊 .

Lo rilascio nel pubblico dominio.

Comunque se volete scaricare video da siti come youtube ed altri, vi consiglio di non adottare questo metodo ma di usare direttamente youtube-dl, che è fantastico!

Panda3D: ruotare la telecamera col mouse

Come l’avevo fatto con Blender, ora lo faccio con Panda3D 😉

Dall’hello world della documentazione ufficiale, ho fatto questo script che muove la telecamera col mouse.

In pratica esegue un task - una funzione eseguita ad ogni frame - che controlla la posizione del mouse, la trasforma da radianti a gradi sessagesimali (usati da Panda) e alla rotazione che ha in quel momento la telecamera aggiunte quella ottenuta con la trasformazione. Infine centra il mouse.

Devo ancora capire perché trasformando le coordinate del mouse - il cui intervallo in panda è [-1; 1] - si riesca a ottenere una buona rotazione con Panda, però sembra funzionare bene!

Ecco lo script python:

#!/usr/bin/env python

from pandac.PandaModules import WindowProperties
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
import math

class MyApp(ShowBase):

	def __init__(self):
		ShowBase.__init__(self)

		# Load the environment model.
		self.environ = self.loader.loadModel("models/environment")
		# Reparent the model to render.
		self.environ.reparentTo(self.render)
		# Apply scale and position transforms on the model.
		self.environ.setScale(0.25, 0.25, 0.25)
		self.environ.setPos(-8, 42, 0)

		# Disable the default camera behavior
		base.disableMouse()
		# Add the mouseCameraTask procedure to the task manager.
		self.taskMgr.add(self.mouseCameraTask, "mouseCameraTask")

	# Define a procedure to move the camera.
	def mouseCameraTask(self, task):
		mw=base.mouseWatcherNode

		# Execute the Task only if the mouse is on the Panda window
		if mw.hasMouse():
			x=mw.getMouseX()
			y=mw.getMouseY()
			curr=self.camera.getHpr()
			self.camera.setHpr(curr.x-x*180/math.pi, curr.y+y*180/math.pi, 0)
			base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2)

		# Continue with the task
		return Task.cont

app = MyApp()
app.run()

Attenzione: vi consiglio di aggiungere un handler al tasto Esc per uscire, in quanto non riuscirete a raggiungere il tasto chiudi. Altrimenti dovete fare come me: usare le combinazioni di tasti Alt + Tab su GNOME per passare in un’altra finestra. In Windows dovrebbe essere sempre Alt + Tab o Super + Tab. In ogni caso lì c’è anche il Task Manager.

Socket e thread in Python

Chi è interessato a sviluppare un’applicazione che utilizzi in un modo anche semplice la rete deve spesso documentarsi sulle socket, in qualsiasi linguaggio di programmazione, anche per il python.

In questo campo ho lavorato più di una volta, però mi sono limitato alla creazione di socket con una sola connessione alla volta.

Tuttavia non è molto utile: penso che la maggior parte delle applicazioni pratiche richiedano più di un client connesso e “addirittura” la possibilità di dialogare tra di loro.

Quindi intervengono i thread.

Non so darvi la spiegazione tecnica di cosa siano, però so darvi una spiegazione pratica: i thread permettono di eseguire contemporaneamente più operazioni, senza però creare un altro processo. Il vantaggio è che si ottiene il famoso multi tasking.

Documentandomi ho trovato che uno degli svantaggi è che non avviene il controllo sull’uso contemporaneo di alcune risorse come file, tuttavia in questo caso usiamo solo la RAM e perciò non ci poniamo il problema.

In python usare i thread è abbastanza semplice: una volta importato il modulo threading o solamente la classe Thread da esso, bisogna estenderla e fare una funzione chiamata run in cui bisogna mettere il codice da eseguire. … [Leggi il resto]

Blender: ruotare la camera col mouse

Continuano i miei esperimenti con Blender.

Una delle mie più grandi domande riguardanti la game mode è: come fare per spostare la telecamera col movimento del mouse?

Beh, mi sono messo ad affrontare questo problema.

Il metodo che io utilizzerei è quello di analizzare il movimento del mouse e quindi di applicarlo alla rotazione.

Per fare ciò è mia intenzione associare uno script python al controller mousemove.

Ecco un prototipo di codice, con i commenti che spiegano cosa fa questo codice:

# Importa le librerie basi: la bge e classi utili da mathutils
import bge
from mathutils import *

# Comincia la funzione main
def main():

    # Prende l'oggetto del controller
    cont = bge.logic.getCurrentController()
    # Prende l'oggetto a cui il controller è applicato
    own = cont.owner
    # Per comodità ci salviamo i globalDict come obj
    obj = bge.logic.globalDict

    # Prendiamo il movimento del mouse
    mousemove=cont.sensors['Mousemove']
    pos=mousemove.position

    # Se è il primo movimento dobbiamo inizializzare i salvataggi dei movimenti
    if not 'mousepos' in obj:
        obj['mousepos']=pos

    # Salviamo il movimento
    obj['oldmousepos']=obj['mousepos']
    obj['mousepos']=pos

    # Troviamo le variazioni
    deltax=obj['mousepos'][0]-obj['oldmousepos'][0]
    deltay=obj['mousepos'][1]-obj['oldmousepos'][1]

    # Creiamo il vettore ed eseguiamo la rotazione lungo l'asse delle z (globale)
    rot=Vector((deltay*0.005, 0.0, -deltax*0.005))
    own.applyRotation(rot, False)

    # Creiamo il vettore ed eseguiamo la rotazione lungo l'asse delle y (locale della camera)
    rot=Vector((-deltay*0.005, 0.0, 0.0))
    own.applyRotation(rot, True)

# Esegue main, ogni volta che il mouse viene mosso
main()

Il risultato è ancora molto primitivo, ma sempre meglio che nulla 😉

In alcuni giochi come i FPS questo movimento è essenziale e andrebbe definito meglio, però questo mi pare già un inizio non malvagio.

Bisognerebbe aggiungere un po’ di controlli per vedere che il mouse non vada fuori dallo schermo e sistemare un po’ i coefficienti della rotazione.

pyLoad

Qualche giorno fa avevo detto che mi serviva un downloader in stile jDownloader.

Quest’ultimo è ottimo, però ha due grossi problemi: è pesante e necessita di X.Org o un altro server X su Linux.

Così mi serviva un’alternativa le cui caratteristiche dovevano essere queste:

  1. Ovviamente funzionare su Linux (il muletto ha Debian 😉 )
  2. Essere più leggero di jDownloader
  3. Possibilmente essere software libero
  4. Non aver bisogno di un server X attivo
  5. Possibilmente non essere scritto in Java

Inizialmente stavo pensando di scrivermene uno io, però sarebbe stato difficile. Per la parte dell’interfaccia mi sarei accontentato, però mi sarebbe stata sicuramente utile la funzione di decodifica captcha automatica, troppo difficile per me.

Google mi ha aiutato: immediatamente mi ha dato ciò che cercavo: pyLoad.

Mi è subito parso buono: è multipiattaforma, è così leggero da funzionare anche sui router, è rilasciato sotto la GPL. È multi interfaccia: ha sia l’interfaccia a linea di comando, sia una grafica sia un’interfaccia web che volendo si può dotare di SSL. In più, si capisce subito dal nome, è scritto in python. … [Leggi il resto]