Foro de elhacker.net

Programación => Java => Mensaje iniciado por: ls_52 en 7 Marzo 2016, 14:08 pm



Título: [Aporte]Aplicar desfase a archivo de subtitulos .srt
Publicado por: ls_52 en 7 Marzo 2016, 14:08 pm
Hola a todos. Me he registrado en la pagina mayormente porque quiero hacer un aporte que, si bien alguien ya ha aportado esto alguna vez, me pase 3 días buscando y no encontré nada, así que debe haber pocos aportes de este tema en particular y como me generó muchos quebraderos de cabeza, quiero que nadie vuelva a pasar por el calvario que pase yo

Intente hacerlo a mano, pero para archivos .srt de 5 o 10 entradas de subtitulos es pasable, pero una de 1500 entradas de subtitulos (como en mi caso) no es buena idea hacerlo a mano
Solo hacer 100/1500 me llevo casi 3 horas a mano y me canse y decidi hacer una aplicacion java que me hiciera el trabajo xD

Lo que aquí traigo es una aplicación JAVA que lee un fichero .txt con una estructura de archivo .srt de subtitulos sin estilo y a cada linea de tiempo le aplica un desfase constante (positivo o negativo) deseado. Debe estar en txt porque no encontre la forma de acceder directamente al .srt desde java y debe ser sin estilo porque si no, la cosa cambia drásticamente

El aspecto del txt debe ser tal que así:

1
0x:xx:xx,xxx --> xx:xx:xx,xxx
comentarios

2
0x:xx:xx,xxx --> xx:xx:xx,xxx
comentarios

.
.
.


Y el codigo en JAVA es este:

Código:
//Importo los paquetes que voy a usar
//I import everything i'm going to use
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

//Nombre de la clase = nombre del archivo .java (puede ser cualquiera)
//Class name = file name (whatever you want)
public class LecturaTxt {
   
    //metodo para cambiar el contenido del archivo txt, contemplando las excepciones de "archivo no encontrado" y "Exccepcion en Input/Output"
    //method for changing the txt content, with "FileNotFoundException" and "Input/Output Error"
    public static void cambiarContenido(String archivo) throws FileNotFoundException, IOException {
        String cadena;
        //Le indico los delimitadores que usara como referencia para despues parsear a partir de ellos
        //I inicialize delimiters that the aplication will use to parse
        String del1 = " --> ";
        String del2 = ":";
        String del3 = ",";
       
        String[] tiempo;
        String[]thmsInicio;
        String[]thmsFinal;
        String[]thmsSepInicio;
        String[]thmsSepFinal;
        //Abro el archivo de texto
        //I open the txt file
        FileReader f = new FileReader(archivo);
        BufferedReader b = new BufferedReader(f);
        //Inicializo variables que luego usare
        //I inicialize some things that i will use
        int minutoInicio = 0;
        int minutoFinal = 0;
        int horaInicio = 0;
        int horaFinal = 0;
        //Leo el arhcivo
        //I read the file
        while(((cadena = b.readLine())!=null)) {
            //Compruebo en cada pasada si la cadena es vacia
            //If the string i read is empty or not
            if((cadena != null) && (!cadena.equals(""))){
                //Compruebo si el primer caracter de la cadena leida empieza por 0 (linea de tiempo)
                //I search for a line begun by 0 (timeline)
                if(cadena.charAt(0) == '0'){
                    //tiempo es String[]tiempo. 00:00:00,000 --> 00:00:00,000 pasa a almacenarse solo los codigos de tiempo sin "-->"
                    //tiempo is String[]tiempo. 00:00:00,000 --> 00:00:00,000 tiempo only save timecodes w/o "-->"
                    tiempo = cadena.split(del1);
                    //thmsInicio = 00:00:00,000 delimitado por ",". Por tanto thmsInicio[0] = "00:00:00" y thmsInicio[1] = "000"
                    thmsInicio = tiempo[0].split(del3);
                    //thmsFinal es lo mismo que thmsInicio
                    //thmsFinal is the same than thmsInicio
                    thmsFinal = tiempo[1].split(del3);
                    //thmsSepInicio es 00:00:00 delimitado por ":". Por lo tanto, thmsSepInicio[0] = "00"(horas), thmsSepInicio[1] = "00" (minutos) y thmsSepInicio[2] = "00"(segundos)
                    thmsSepInicio = thmsInicio[0].split(del2);
                    //thmsSepFinal es lo mismo que thmsSepInicio
                    //thmsSepFinal is the same than thmsSepInicio
                    thmsSepFinal = thmsFinal[0].split(del2);
                    //Me voy a los milisegundos y le aplico el desfase deseado
                    //I go to milliseconds and i apply the wished delay
                    int milsegInicioNuevo = Integer.parseInt(thmsInicio[1]) + 350;
                    int milsegFinalNuevo = Integer.parseInt(thmsFinal[1]) + 350;
                    //Voy a segundos y le aplico el desfase deseado
                    //I go t seconds and i apply the wished delay
                    int segInicioNuevo = Integer.parseInt(thmsSepInicio[2]);
                    segInicioNuevo = segInicioNuevo + 39;
                    int segFinalNuevo = Integer.parseInt(thmsSepFinal[2]);
                    segFinalNuevo = segFinalNuevo + 39;
                    //Extraigo las horas y los minutos de inicio y final
                    //I extract hours and minutes from begin and finish
                    minutoInicio = Integer.parseInt(thmsSepInicio[1]);
                    minutoFinal = Integer.parseInt(thmsSepInicio[1]);
                    horaInicio = Integer.parseInt(thmsSepInicio[0]);
                    horaFinal = Integer.parseInt(thmsSepInicio[0]);
                    //Si al aplicarle el desfase, los milisegundos pasan de 1000, sumar 1 segundo
                    //If after for applying the delay, milliseconds are exceeded of 1000, add 1 to seconds
                    if(milsegInicioNuevo >= 1000){
                        milsegInicioNuevo = milsegInicioNuevo - 1000;
                        segInicioNuevo = segInicioNuevo + 1;
                        //Si despues de aplicar el desfase, los segundos pasan de 60, sumar 1 a minuto
                        //If after for applying the delay, seconds are exceeded of 60, add 1 to minutes
                        if(segInicioNuevo >= 60){
                            segInicioNuevo = segInicioNuevo - 60;
                            minutoInicio = Integer.parseInt(thmsSepInicio[1]) + 1;
                            //Si despues de aplicar el retraso , los minutos pasan de 60, sumar 1 a la hora
                            //If after applying the delay, minutes are exceeded of 60, add 1 to hour
                            if(minutoInicio >= 60){
                                minutoInicio = minutoInicio - 60;
                                horaInicio = Integer.parseInt(thmsSepInicio[0]) + 1;
                            }
                        }
                    }
                    if(milsegFinalNuevo >= 1000){
                        milsegFinalNuevo = milsegFinalNuevo - 1000;
                        segFinalNuevo = segFinalNuevo + 1;
                        if(segFinalNuevo >= 60){
                            segFinalNuevo = segFinalNuevo - 60;
                            minutoFinal = Integer.parseInt(thmsSepInicio[1]) + 1;
                            if(minutoFinal >= 60){
                                minutoFinal = minutoFinal - 60;
                                horaFinal = Integer.parseInt(thmsSepInicio[0]) + 1;
                            }
                        }
                    }
                    if(segInicioNuevo >= 60){
                        segInicioNuevo = segInicioNuevo - 60;
                        minutoInicio = Integer.parseInt(thmsSepInicio[1]) + 1;
                        if(minutoInicio >= 60){
                            minutoInicio = minutoInicio - 60;
                            horaInicio = Integer.parseInt(thmsSepInicio[0]) + 1;
                        }
                    }
                   
                    if(segFinalNuevo >= 60){
                        segFinalNuevo = segFinalNuevo - 60;
                        minutoFinal = Integer.parseInt(thmsSepInicio[1]) + 1;
                        if(minutoFinal >= 60){
                            minutoFinal = minutoFinal - 60;
                            horaFinal = Integer.parseInt(thmsSepInicio[0]) + 1;
                        }
                    }
                    //Imprimir cadena siguiendo la estructura 00:00:00,000 --> 00:00:00,000
                    System.out.println("0"+horaInicio+":"+minutoInicio+":"+segInicioNuevo+","+milsegInicioNuevo+" --> "+horaFinal+":"+minutoFinal+":"+segFinalNuevo+","+milsegFinalNuevo);
                }else{
                    //Si la cadena leida no empieza por 0, imprimir cadena leida
                    //If read string is not begun by 0, write read line
                    System.out.println(cadena);
                }
            }else{
                //Si la cadena leida es vacia, dejar espacio en blanco
                //If readline is empty, set blank
                System.out.println();
            }
        }
        //cierro documento leido
        //close read document
        b.close();
    }

    public static void main(String[] args) throws IOException {
        //llamada a metodo
        //call to method
        cambiarContenido("borra todo y pon la diceccion del archivo aqui // erase all and put the file address here");
    }


Soy consciente que se puede depurar muchisimo mi codigo, como poner un scanner para leer los datos de desfase, o hacer que el resultado lo escriba en otro documento de texto o que sustituya el que esta leyendo o simplemente hacerlo sin tantas variables, pero no quise romperme mas la cabeza

Espero que a ustedes les ayude tanto como a mi :)