Etiquetas

555 74HC04 74HC14 74HC165 74LS04 acentos ADC10 Amstrad archivo arduino aristóteles armbian array ass at backup base64 bash Basho bc beethoven Biblia blog bucle c c++ c++11 c++17 C005 cadena Carmina Burana casting CD4017 CD4040 Cine clases Colores connect Consolación a Helvia Consolación a Marcia Consolación a Polibio constante corsair CPC Cristal 32Khz css cursor mouse cut daemon date dead keys Debian directorio disco duro DS32kHz electricidad Electrónica ensamblador entryList epicureismo Estadística estoicismo felicidad ffmpeg filePath filosofia Filosofía firefox flac for fstab funcion Gargantúa gastronomía gilgamesh Ginott gmp gpt grep gtts Hobbes hotkeys html imagemagick inline Javascript kde kernel modulos latex ldr lib-notify Linux Literatura ludoteca macro mapa de bits Matroska mega Microsoft Word Milan Kundera mkvextract mkvinfo mount mp3 mplayer MSP430 msp430F5529 MSP432 Multimedia Musica oop orange_pi pato PIR PL9823 Platón poesía POO en C++ pulseaudio puntero PWM pygame pyqt python QAction qApp QApplication QByteArray QDialog Qdir QFile QFileDialog QImage qlabel QList QListWidget QMessagebox QMouseEvent qpainter QPalette QPixmap QProcess QRegularExpression QRegularExpressionMatchIterator QString QStringList Qt qt5 QToolbar quijote QVector qwidget R Rabelais ratón relé Resonador cerámico samba San Agustín screen Séneca signal slot smart smartctl sox srt static const stdarg.h subtítulos Symbian tar teléfonos móviles temperatura temperatura cpu Temporizador tesseract Timer timestamp Trigonometría tts tutorial uid unicode user USI va_arg va_end va_list va_start velocidad ventilador Voltaire wallpaper xboxdrv xinput xrandr Z80 zip

sábado, julio 14, 2018

Extracción de subtitulos de un contenedor Matroska en Linux

Hace siete años escribí una entrada de como se extraían los subtítulos. Ha pasado mucho tiempo y no me acordaba de haber escrito sobre el tema. A continuación la extracción de los subtítulos en un contenedor Matroska desde Linux en 2018.

Versión de 2011

Versión de 2023 

 

Aviso:
Con este proceso se obtiene un archivo de texto en formato srt. Desconozco otros formatos.

1. Preparativos.
Si es necesario, instalar mkvtoolnix

aptitude install mkvtoolnix

2. Examinar el contenido del archivo: mkvinfo 

mkvinfo movie.mkv

y el resultado resumido:
+ Encabezado EBML
|+ Versión EBML: 1
|+ Versión de lectura EBML: 1
|+ Máxima extensión de la ID de EBML: 4
|+ Máxima extensión de tamaño de EBML: 8
|+ Tipo de documento: matroska
|+ Versión del tipo de documento: 4
|+ Leer versión del tipo de documento: 2
...
+ Pistas del segmento
| + Una pista
|  + Número de pista: 1 (ID de pista para mkvmerge y mkvextract: 0)
|  + Pista UID: 375332386959707365
|  + Tipo de pista: video
...
| + Una pista
|  + Número de pista: 2 (ID de pista para mkvmerge y mkvextract: 1)
|  + Pista UID: 9142038347006410126
|  + Tipo de pista: audio
|  + ID del códec: A_AAC
...
| + Una pista
|  + Número de pista: 3 (ID de pista para mkvmerge y mkvextract: 2)
|  + Pista UID: 6173318127436163630
|  + Tipo de pista: subtitles
|  + Flag de atadura: 0
|  + ID del códec: S_TEXT/UTF8
...

Lo importante es que la pista de subtítulos es la 3 (en mkvinfo) y 2 (en mkvextract, que es la que nos interesa).


3. Extraer los subitulos: mkvextract
mkvextract tracks movie.mkv 2:movie.srt

Terminado. Los subtítulos están disponibles en movie.srt.

Más información:
http://cristian.sulea.net/blog.php?p=2014-12-15-extract-mkv-matroska-subtitles-on-linux-ubuntu

martes, mayo 01, 2018

Hola mundo en ensamblador para el Amstrad CPC


Explicación:
Lineas 20 y 50. La cadena de texto se coloca entre dos etiquetas MSG_START y MSG_END. Se pueden poner los DEFM que se quiera. El DEFB 13,10 es el salto de linea y retorno de carro.

Linea 100. Para el bucle de impresión se utiliza el registro B. La longitud de la cadena se calcula restando MSG_END de MSG_START.

Linea 110. La dirección de comienzo de la cadena se guarda en el registro de 16 bits DE.

Linea 120. La etiqueta del bucle.

Linea 130. Se carga en el registro A el contenido apuntado por el registro DE.

Linea 140. Se imprime el carácter (CALL #BB5A).

Linea 150. Se incrementa en 1 el registro DE

Linea 160. Se decrementa el registro B y se salta al comienzo del bucle si no es 0.

lunes, abril 09, 2018

Mapas de bits en c++

Ejemplo de como guardar un mapa de bits en una variable int y de como leer los bits individuales.

#include

using namespace std;

//Variable para guardar el mapa de bits
int mapa = 0;

// Los bits
int bit0 = 1;
int bit1 = 2;
int bit2 = 4;


int main()
{
    cout << "Hello world!" << endl;
   
    // Poner a 1 el bit 0 y el 2
    mapa |= bit0 | bit2;
    cout << "mapa:" << mapa << endl;
   
    // Lectura de los bits individuales
    cout << "bit0? " << ((mapa & bit0) == bit0) << endl;
    cout << "bit1? " << ((mapa & bit1) == bit1) << endl;
    cout << "bit2? " << ((mapa & bit2) == bit2) << endl;
    cout << endl;
   
    // Poner a 0 el bit 2
    mapa &= ~bit2;
   
    // Lectura de los bits individuales
    cout << "bit0? " << ((mapa & bit0) == bit0) << endl;
    cout << "bit1? " << ((mapa & bit1) == bit1) << endl;
    cout << "bit2? " << ((mapa & bit2) == bit2) << endl;

    return 0;
}

jueves, noviembre 16, 2017

Creación de un demonio en la Orange Pi Zero

1. Instalar python-daemon.
2. Escribir el script en python.
3. Crear el script de arranque a partir de /etc/init.d/skeleton.
Si el script a partir de skeleton se queda corto, consultar esto:
https://descubriendolaorangepi.wordpress.com/2017/02/16/instalar-y-configurar-servidor-vnc/
4. Hacer el script ejecutable. 
5. Actualizar el arranque:
update-rc.d defaults

 6. Un ejemplo:
import os
import sys
import time
import daemon
import signal


from pyA20.gpio import gpio
from pyA20.gpio import port

PIN_READY = port.PA7
PIN_TURNOFF = port.PA6

class GracefulKiller:
    kill_now = False
    def __init__(self):
        signal.signal(signal.SIGINT, self.exit_gracefully)
        signal.signal(signal.SIGTERM, self.exit_gracefully)

    def exit_gracefully(self, signum, frame):
        self.kill_now = True


# Parte principal del programa
def mainLoop():
    # Inicializa la finalización del programa
    killer = GracefulKiller()

    # Inicializa gpio
    gpio.init()
    gpio.setcfg (PIN_READY, gpio.OUTPUT)
    gpio.setcfg (PIN_TURNOFF, gpio.INPUT)
    gpio.pullup (PIN_TURNOFF, 0)    # clear pullup
    gpio.output (PIN_READY, 1)

    # Bucle infinito
    while True:
        if gpio.input(PIN_TURNOFF) == gpio.LOW:
            os.system("shutdown -h now")

        time.sleep(0.1)

def run():
    with daemon.DaemonContext():
        mainLoop()

if __name__ == "__main__":
    run()


Referencias:
https://wiki.debian.org/LSBInitScripts
https://stackoverflow.com/questions/18499497/how-to-process-sigterm-signal-gracefully
https://pypi.python.org/pypi/python-daemon/
https://stackoverflow.com/questions/4637420/efficient-python-daemon
 https://enavas.blogspot.com.es/2008/12/update-rcd-actualizando-el.html

viernes, octubre 27, 2017

Detector de presencia con LDR

El circuito lo he sacado de youtube.

miércoles, septiembre 27, 2017

La vida de los objetos en C++ (2)

1. El programa

El programa es similar al anterior.

Aquí aparece una función llamada villaBotijos en la que se crean y se destruyen las Personas.
Luis y el Bebe se destruyen automáticamente al terminar la función. Fermín el puntero tiene que ser destruido explicitamente con delete.

La vida de los objetos en c++ (1)

1. Introducción a la clase Persona:
La clase Persona tiene:
Campos: nombre y dinero.
Dos constructores, uno sin parámetros y otro sin parámetros. Por último un destructor.

2. El método main

3. La salida del programa

Comienza el mundo..
Ha nacido un bebe sin dinero :|
Ha nacido Luis con 5000 euros :)
Ha nacido Fermín el puntero con 400 euros :)
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
... y aquí se acaba
Ha muerto Luis con 5000 euros :(
Ha muerto bebe con 0 euros :(

sábado, septiembre 02, 2017

Capturando los eventos del teclado en un QLabel

Para empezar, esto sería una extensión a la captura del ratón que se ha hecho previamente: Captura de los eventos del ratón en un QLabel

1. Redefinir la función keyPressEvent en .h:
protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);


2. En el .cpp
void myLabel::keyPressEvent(QKeyEvent *event){
    // Lista de qt::key http://doc.qt.io/qt-4.8/qt.html#Key-enum

    if (event->key() == Qt::Key_Escape) {
        qDebug() << "Escape";
    } else {
        qDebug() << "tecla" << event->key()  ;
    }
}


3. Modificar la politica del foco en el constructor:
this->setFocusPolicy(Qt::StrongFocus);

4. Para capturar letras acentuadas

Un QMessageBox

    QMessageBox msgBox;

    msgBox.setText("Borrar la imágen.");
    msgBox.setInformativeText("¿Estás seguro?");
    msgBox.setIcon(QMessageBox::Question);
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox.setDefaultButton(QMessageBox::No);
    int ret = msgBox.exec();

    if (ret == QMessageBox::Yes) {
        container.ClearImage();
    }

miércoles, agosto 30, 2017

Modulo relé para Arduino


Captura de los enventos del ratón en un QLabel

1. Lo primero es derivar una clase de QLabel que modifique las siguientes funciones protegidas:

 #include

class myLabel : public QLabel
{
    Q_OBJECT
public:
    explicit myLabel(QWidget *parent = 0);

 };

protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);


Y para enviar la posición del ratón a otros controles voy a crear una señal a propósito:

signals:
    void mouseOver (QPoint point);


2.  Insertar myLabel en la MainWindow:

#include "mylabel.h"

    myLabel *ml = new (myLabel);
    ml->setText("Pasa el ratón por aquí");
    //ui->horizontalLayout->addWidget(ml);
    ui->horizontalLayout->insertWidget(0,ml);


horizontalLayout tiene dos métodos para insertar los widget: addwidget (al final) y insertWidget (indicando el índice dentro el layout).

3. En el constructor de myLabel activar el mouse tracking:

myLabel::myLabel(QWidget *parent) :
    QLabel(parent)
{
    this->setText("Hola");
    this->setMouseTracking(true);
    this->setFrameShape(QFrame::Box);
}


4. Implementar los eventos del ratón.

void myLabel::mouseMoveEvent(QMouseEvent *event){
    QPoint point;
    point = event->pos();
    QString txt;
    txt = QString::number(point.x()) + "," + QString::number(point.y());
    this->setText(txt);

    // Se envia la señal con la posición del ratón
    emit mouseOver(point);

}

void myLabel::mousePressEvent(QMouseEvent *event){
    this->setText("Pulsado");


}

void myLabel::mouseReleaseEvent(QMouseEvent *event){
    this->setText("Soltado");
}


4. En el mainWindow crear un slot para recivir los signals de myLabel:

en mainwindow.h
public slots:
    void updateMousePos(QPoint);


y en mainwindow.cpp
void MainWindow::updateMousePos(QPoint p){
    // Esto lo que hace es mostrar la posición del ratón
    // en dos QLabel
    this->ui->lx->setText (QString::number(p.x()));
    this->ui->ly->setText(QString::number(p.y()));
}




5. Y si quieres capturar el teclado Capturando los eventos del teclado en un QLabel

viernes, junio 23, 2017

Dibujo básico con QT


En resumen:
1. Necesitas un QMainWindow (una ventana) para la aplicación

2. Dentro del QMainWindow un QLabel que se encarga de mostrar el dibujo

3. Un QImage para guardar el dibujo en memoria
   QImage * img = new QImage (640,480,QImage::Format_RGB32);

4. Un QPainter para tener donde dibujar.
     QPainter paint(img);
  paint.setPen(QColor::fromRgb(200,200,10));
  paint.drawLine(10,10,100,100);
  paint.drawText(50,50,"Hola");


Para el color puedes utilizar la funcion estática
  QColor::fromRgb(r,g,b);
y que no se olvide un
  #include "QColor"


5. Terminado el dibujo hay que convertirlo en QPixmap para que lo muestre el QLabel
   ui->vista->setPixmap(QPixmap::fromImage(*img));

jueves, junio 08, 2017

domingo, mayo 28, 2017

Montar lapiz USB al arranque de la Orange PI Zero

Montar lapiz USB al inicio como solo lectura.
Añadir esta linea al fstab:
 UUID=9025b4f4-c6bd-4b76-9da8-b5638a4f5aba /media/tdk auto ro,nosuid,nodev,nofail 0 0

Para obtener el UUID:
blkid /dev/sda1
(Suponiendo que el lapiz usb está montado como /dev/sda1

Para montarlo manualmente:
mount -o ro /dev/sda1 /media/tdk/

miércoles, mayo 24, 2017

Caida de voltage en circuito con mosfet n-channel

IRF510
5.4V - 0A
4.8V - 0.17A

IRFS 630B
5.4V - 0A
5.0V - 0.29A

sábado, abril 29, 2017

Error en la depuración programando un MSP430

Durante la depuración aparecía el siguiente error en la consola:
MSP430: Trouble Reading Memory Block at 0x2f8 on Page 0 of Length 0x2: Could not determine device state

Solución:
El MSP430 tiene varios Leds conectados directamente de las salidas. Un condensador de 470 uF entre VCC y GND soluciona el problema.

sábado, abril 08, 2017

lunes, abril 03, 2017

Añadir un usario a la Orange Pi Zero

1. Crear el usuario
adduser

2. Si algo falla:
2a. Borrar el usuario
userdel -r

2b. Añadir el usuario a un grupo:
adduser

2c. Ver los grupos disponibles:
cat /etc/group

martes, marzo 21, 2017

Screen en la orange pi zero

La conexion por ssh con la OPI Zero se puede interrumpir. Para mantener la sesión abierta aunque la conexión se pierda hay una utilidad de linux llamada screen.

Para empezar:
screen

Para recomenzar tras la perdida de la conexión:
screen -r

Para ver la misma sesión desde dos dispositivos
screen -x

Crear nueva ventana:
Ctrl+A "C"

Cerrar una ventana desde bash
exit

Siguiente ventana:
Ctrl+A "N"

Previa ventana:
Ctrl+A "P"





Más info aquí: https://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/

lunes, marzo 20, 2017

Lectura de la temperatura de la CPU de la Orange Pi Zero desde python

#Esta función retorna un int con la temperatura de la CPU
def getTemperature():
    file = open("/sys/class/thermal/thermal_zone0/temp","r")
    t = file.read()
    file.close()
    return int (t)