Quero criar um programinha pra resyncronizar legendas de uma forma bem simples.
Estou com um problema na hora de regravar os novos valores para dos tempos das legendas.
Basicamente, estou lendo a legenda antiga, atualizando os tempos, e nesse meio tempo vou gravando novamente as legendas em um arquivo temporario.
Aqui vai o código:
FileReader reader = new FileReader(arquivo);
FileWriter writer = new FileWriter("d:/temp.srt");
BufferedReader leitor = new BufferedReader(reader);
Parser parser = new Parser();
String tempo = null;
String tempoInicio = null;
String tempoFim = null;
String numero = null;
String tempoInicioS = null;
String tempoFimS = null;
String tempoS = null;
int tempoInicioMilisec;
int tempoFimMilisec;
do{
if(leitor.readLine().equals("")){
numero = leitor.readLine();
tempo = leitor.readLine();
tempoInicio = String.copyValueOf(tempo.toCharArray(), 0, 12);
tempoFim = String.copyValueOf(tempo.toCharArray(),17,12);
tempoInicioMilisec = parser.retornaTempoEmMiliSec(tempoInicio);
tempoFimMilisec = parser.retornaTempoEmMiliSec(tempoFim);
tempoInicioMilisec = tempoInicioMilisec + milisegundos;
tempoFimMilisec = tempoFimMilisec + milisegundos;
tempoInicioS = parser.retornaTempoEmString(tempoInicioMilisec);
tempoFimS = parser.retornaTempoEmString(tempoFimMilisec);
tempoS = tempoInicioS+" --> "+tempoFimS;
writer.write("\r\n");
writer.write(numero+"\r\n");
writer.write(tempoS);
writer.write("\r\n");
}
}while(leitor.ready());
Se eu colocar uns println’s no meio, todos os valores estão correts e o leitor consegue varrer a legenda inicial até o fim. O problema, é que no arquivo de saida, apenas parte das informações é copiada,e no meio da execução ele dispara um NullPointerException nessa instrução tempoInicio = String.copyValueOf(tempo.toCharArray(), 0, 12); . Não estou entendendo o que pode estar acontecendo, já que em nenhum momento, a variavel tempo fica nula.
Imprima duas linhas antes e duas linhas depois onde está ocorrendo esse erro… que pode te ajudar, muito provavel ser um problema no srt.
Então, eu já fiz isso, e ele le e imprime todas as linhas normalmente, o problema é que no arquivo de saida ele para no meio … Geralmente umas 150 linhas antes de terminar o arquivo de entrada.
Queres que eu poste as entradas e saidas e os arquivos?
[quote=AndreMendes]Então, eu já fiz isso, e ele le e imprime todas as linhas normalmente, o problema é que no arquivo de saida ele para no meio … Geralmente umas 150 linhas antes de terminar o arquivo de entrada.
Queres que eu poste as entradas e saidas e os arquivos?[/quote]
Tipo pra ajudar poste um pedaço do arquivo e como espera a saída ou como espera que a saída seja (de acrodo com seu sparametros)
De uma olhada nos arquivos de entrada e saida.
A saida espera é algo no formato
//um numero
##:##:##,### --> ##:##:##,### //o tempo da legenda acrescido do tempo necessario, nesse caso 2000 milisec
// linha em branco
e tudo se repete …
O que acontece, é que apenas parte do arquivo de entrada é copiado …
E como pretente interagir e tipo informar qual linha deseja mudar?
Esse nao é o problema na verdade.
As legendas sempre vem no padrao
NUMERO
TEMPO
LEGENDA
PULA UMA LINHA
Então nao ficou dificil. Tente executar esse metodo para ver o que acontece.
Estou pensando numa solução mais ou menos assim.
try {
FileReader legendaAModificar = new FileReader("/home/leandro-rm/Downloads/teste.srt");
Legenda legenda = getLegenda(legendaAModificar);
//pode-se iterar pe
List<Linha> linhas = legenda.getLinhas();
//ou alterar linha 3
legenda.getLinha(3).setInicio("");
legenda.salvar("novo.srt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Voce quer passar as obrigações de leitura e escrita para uma classse Legendas?
E fazer toda a manipulação dos dados lá dentro ?
Você acha que isso resolverá meu problema?
Tente executar o método, para o ver o problema que acontece …
[quote=AndreMendes]Voce quer passar as obrigações de leitura e escrita para uma classse Legendas?
E fazer toda a manipulação dos dados lá dentro ?
Você acha que isso resolverá meu problema?
Tente executar o método, para o ver o problema que acontece …[/quote]
Na verdade não estou tentando resolver o seu problema lá do código estou escrevendo um código que faça a mudança e salve um arquivo com as mudanças que deseja!
Vou tentar fazer dessa forma para ver se o erro não acontece mais.
Vou fazer com que essa classe legendas faça todo o “trabalho sujo”.
Mais tarde eu posto o que aconteceu aqui.
Consegui fazer de um modo aqui, não sei se te serve ao todo. O teste abaixo lê a legenda teste.srt e modifica a linha 3 setando o tempo inicio para e salva num arquivo chamado novo.srt. Nos testes que fiz aqui funcionou.
FileReader legendaAModificar = new FileReader("/home/leandro-rm/Downloads/teste.srt");
Legenda legenda = new Legenda(legendaAModificar);
legenda.getLinha(3).setInicio(":P");
legenda.salvar("novo.srt");
O código todo segue abaixo pra modificação, melhoria, adaptações… enfim! Críticas, sugestões.
[code]package br.com.leandromoreira.legenda;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
public class ServicoLegenda {
public static class Legenda{
private List linhas = new LinkedList<ServicoLegenda.Linha>();
public Legenda(FileReader legenda) {
BufferedReader bf = new BufferedReader(legenda);
try {
String linha = bf.readLine();
while (linha != null){
int id = Integer.valueOf(linha.trim());
linha = bf.readLine();
String tempo = linha.trim();
String inicio = tempo.split("–>")[0].trim();
String fim = tempo.split("–>")[1].trim();
StringBuilder texto = new StringBuilder();
String textTmp = bf.readLine();
while (!textTmp.trim().equals("")){
texto.append(textTmp+"\n");
textTmp = bf.readLine();
}
linhas.add(new Linha(id,inicio,fim,texto.toString()));
linha = bf.readLine();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public List<Linha> getLinhas() {
return linhas;
}
public void salvar(String arquivo) {
try {
FileWriter arquivoASalvar = new FileWriter(new File(arquivo));
for (Linha linha : linhas) {
arquivoASalvar.write(linha.toString());
arquivoASalvar.write("\n");
}
arquivoASalvar.flush();
arquivoASalvar.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public Linha getLinha(int i) {
return linhas.get(i-1);
}
@Override
public String toString() {
return "Legenda [linhas=" + linhas + "]";
}
}
public static class Linha{
private int numero;
private String inicio;
private String fim;
private String texto;
public Linha(int numero, String inicio, String fim, String texto) {
super();
this.numero = numero;
this.inicio = inicio;
this.fim = fim;
this.texto = texto;
}
public int getNumero() {
return numero;
}
public void setNumero(int numero) {
this.numero = numero;
}
public String getInicio() {
return inicio;
}
public void setInicio(String inicio) {
this.inicio = inicio;
}
public String getFim() {
return fim;
}
public void setFim(String fim) {
this.fim = fim;
}
public String getTexto() {
return texto;
}
public void setTexto(String texto) {
this.texto = texto;
}
@Override
public String toString() {
return + numero + "\n" +
inicio + " --> "+ fim + "\n"
+ texto;
}
}
public static void main(String[] args) {
try {
FileReader legendaAModificar = new FileReader("/home/leandro-rm/Downloads/teste.srt");
Legenda legenda = new Legenda(legendaAModificar);
legenda.getLinha(3).setInicio(":P");
legenda.salvar("novo.srt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
[/code]
Agora vocẽ pode trabalhar na classe Linha e melhorando e adaptando para sua necessidade, eu coloquei como se o tempo fosse inicial e final e pronto. Se quiser especifcar outro métodos como :
public inteface Linha{
void adicionarMilessegundosInicio(int tempoMS) ;
void subtrairMilessegundosFim(int tempoMS);
}
Enfim agora é sua criatividade e necessidade. Disse para colocá-los em linha por conta da facilidade da manutenção, já sabe que está na linha #3 e blá blá blá blá …
Claro que pode também fornecer esse métodos para rolar toda legenda pra frente… daí aplica essas mudanças a todas as Linha’s!
legenda.rolarMsParaFrente(100); //adianta toda legenda
Perfeito. Misturei seu codigo com o meu e funcionou, apesar de eu não ter identificado meu erro no código anterior.
Agora o problema são os caracteres especiais. Quando vou checar o arquivo de saida, todos os acentos foram omitidos. Isso ocorre durante a manipulação das Strings dentro do código. Alguma ideia de como solucionar isso? Vou ver se acho algo no google e depois posto aqui!
[quote=AndreMendes]Perfeito. Misturei seu codigo com o meu e funcionou, apesar de eu não ter identificado meu erro no código anterior.
Agora o problema são os caracteres especiais. Quando vou checar o arquivo de saida, todos os acentos foram omitidos. Isso ocorre durante a manipulação das Strings dentro do código. Alguma ideia de como solucionar isso? Vou ver se acho algo no google e depois posto aqui![/quote]
Provavelmente codificação ISO --> UTF. Veja e poste aqui mesmo.
Achei este tópico no GUJ mesmo. Parece que tinham o mesmo problema que o meu.
http://javafree.uol.com.br/topic-876655-Caracteres-especiais-em-arquivo-txtResolvido.html
Essa alteração é valida porque, na hora em que o compilador gera o byte code para a JVM, a codificação é opcional ?
É isso? Estou errado?
Sou grato a você que me ajudou muito!!!
Essa parte do projeto foi concluida, agora vou dar uma cara para o resync e vou postar ele pronto depois.
[quote=AndreMendes]Sou grato a você que me ajudou muito!!!
Essa parte do projeto foi concluida, agora vou dar uma cara para o resync e vou postar ele pronto depois.
[/quote]
quando alguém ensina aprende duas vezes!