Pisahkan file .srt menjadi beberapa bagian yang sama

Saya baru dalam hal ini dan saya perlu membagi Srt (file subtitle) menjadi beberapa bagian.

Misalnya: jika saya memiliki file subtitle suatu video (60 menit). Kemudian file subtitle harus dipecah menjadi 6 file subtitle yang masing-masing file subtitle berdurasi 10 menit.

yaitu 6 X 10 = 60 Menit

Perlu dibagi menjadi 6 bagian berapapun menitnya.

Dengan menggunakan setiap waktu/durasi subtitle, saya harus membagi video menjadi beberapa bagian yang sama.

Saya mencoba kode ini, bisakah Anda membantu saya bagaimana cara menghitung waktu dan membaginya menjadi beberapa bagian,

Saya dapat mencapai berapa menit chuck yang saya perlukan. Tetapi terjebak dalam cara membaca hingga menit-menit itu dari file sumber dan membuat file baru. Lalu bagaimana memulai potongan berikutnya dari 10 menit berikutnya dari file sumber.

import org.apache.commons.io.IOUtils;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;

/**
 * The class SyncSRTSubtitles reads a subtitles .SRT file and offsets all the
 * timestamps with the same specific value in msec.
 *
 * The format of the .SRT file is like this:
 *
 * 123
 * 00:11:23,456 --> 00:11:25,234
 * subtitle #123 text here
 *
 *
 * @author Sorinel CRISTESCU
 */
public class SyncSRTSubtitles {

    /**
     * Entry point in the program.
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {

        /* INPUT: offset value: negative = less (-) ... positive = more (+). */
        long delta = (22 * 1000L + 000); /* msec */


        /* INPUT: source & destination files */
        String srcFileNm = "/Users/meh/Desktop/avatar.srt";
        String destFileNm = "/Users/meh/Desktop/avatar1.srt";


        /* offset algorithm: START */
        File outFile = new File(destFileNm);
        outFile.createNewFile();
        FileWriter ofstream = new FileWriter(outFile);
        BufferedWriter out = new BufferedWriter(ofstream);

        /* Open the file that is the first command line parameter */
        FileInputStream fstream = new FileInputStream(srcFileNm);
        DataInputStream in = new DataInputStream(fstream);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        String strLine;
//        List<String> doc = IOUtils.readLines(in, StandardCharsets.UTF_8);


String strEnd = null;
        long diff = 0;
        String line;
        String startTS1;
        try (Stream<String> lines = Files.lines(Paths.get(srcFileNm))) {
            line = lines.skip(1).findFirst().get();
            String[] atoms = line.split(" --> ");
             startTS1 = atoms[0];

        }
        System.out.println("bolo:" +line);
        System.out.println("startTS1:" +startTS1);

        String startTS = null;
        String endTS = null;
        /* Read File Line By Line */
        while ((strLine = br.readLine()) != null) {
            String[] atoms = strLine.split(" --> ");
            if (atoms.length == 1) {
                //out.write(strLine + "\n");
            }
            else {
                 startTS = atoms[0];


                 endTS = atoms[1];
//                out.write(offsetTime(startTS, delta) + " --> "
//                    + offsetTime(endTS, delta) + "\n");
                strEnd = endTS;

            }


        }
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm:ss");
            Date parsedendDate = dateFormat.parse(strEnd);
            Date parsedStartDate = dateFormat.parse(startTS1);
            diff = parsedendDate.getTime() - parsedStartDate.getTime();

        } catch(Exception e) { //this generic but you can control another types of exception
            // look the origin of excption
        }
        System.out.println("strEnd");
        System.out.println(strEnd);
        /* Close the input streams */
        in.close();
        out.close();
        System.out.println(diff);
        long diff1 =diff/6;
        System.out.println(diff1);
        long diff2= (diff1*6);
        System.out.println(diff2);
        System.out.println((diff / 3600000) + " hour/s " + (diff % 3600000) / 60000 + " minutes");
        System.out.println((diff1 / 3600000) + " hour/s " + (diff1 % 3600000) / 60000 + " minutes");
        System.out.println((diff2 / 3600000) + " hour/s " + (diff2 % 3600000) / 60000 + " minutes");

        /* offset algorithm: END */
        System.out.println("DONE! Check the rsult oin the file: " + destFileNm);
    }

    /**
     * Computes the timestamp offset.
     *
     * @param ts
     *            String value of the timestamp in format: "hh:MM:ss,mmm"
     * @param delta
     *            long value of the offset in msec (positive or negative).
     * @return String with the new timestamp representation.
     */
    private static String offsetTime(String ts, long delta) {
        long tsMsec = 0;
        String atoms[] = ts.split("\\,");
        if (atoms.length == 2) {
            tsMsec += Integer.parseInt(atoms[1]);
        }
        atoms = atoms[0].split(":");

        tsMsec += Integer.parseInt(atoms[2]) * 1000L; /* seconds */
        tsMsec += Integer.parseInt(atoms[1]) * 60000L; /* minutes */
        tsMsec += Integer.parseInt(atoms[0]) * 3600000L; /* hours */
        tsMsec += delta; /* here we do the offset. */

        long h = tsMsec / 3600000L;
        System.out.println(h);

        String result = get2digit(h, 2) + ":";

        System.out.println(result);


        long r = tsMsec % 3600000L;
        System.out.println(r);

        long m = r / 60000L;
        System.out.println(m);

        result += get2digit(m, 2) + ":";
        System.out.println(result);
        r = r % 60000L;
        System.out.println(r);

        long s = r / 1000L;
        result += get2digit(s, 2) + ",";

        result += get2digit(r % 1000L, 3);
        System.out.println(result);

        return result;
    }

    /**
     * Gets the string representation of the number, adding the prefix '0' to
     * have the required length.
     *
     * @param n
     *            long number to convert to string.
     * @param digits
     *            int number of digits required.
     * @return String with the required length string (3 for digits = 3 -->
     *         "003")
     */
    private static String get2digit(long n, int digits) {
        String result = "" + n;
        while (result.length() < digits) {
            result = "0" + result;
        }
        return result;
    }

}

Tolong sarankan saya bagaimana saya bisa mencapai ini?


person user6250770    schedule 03.07.2018    source sumber
comment
apakah Anda selalu membutuhkannya dalam waktu 10 menit atau bagaimana tepatnya seharusnya?   -  person XtremeBaumer    schedule 03.07.2018
comment
saya perlu dibagi menjadi beberapa bagian yang sama... jika 10 menit, maka jika saya ingin 5 bagian, maka harus dibagi masing-masing 2 menit.. jika saya memiliki file berdurasi 120 menit. jika saya memerlukan 6 potongan, 20 menit untuk setiap file... keluaran seperti itu saya perlu @XtremeBaumer   -  person user6250770    schedule 03.07.2018
comment
Anda memerlukan cara yang konsisten untuk mengetahui berapa banyak potongan yang Anda butuhkan. Berapa banyak potongan yang Anda perlukan untuk 65/79/88 menit?   -  person XtremeBaumer    schedule 03.07.2018
comment
itu mungkin berbeda dari film ke film. Oke, akan diperbaiki menjadi 6 potongan selama beberapa menit. Dan keenamnya harus ditulis dalam 6 file .srt   -  person user6250770    schedule 03.07.2018
comment
@XtremeBaumer membutuhkan 6 potongan berapapun menitnya. dan itu harus ditulis dalam 6 file .srt yang berbeda. Bagaimana saya bisa mencapai ini? tolong sarankan   -  person user6250770    schedule 03.07.2018
comment
Jika Anda tidak mengetahui durasi video sebelumnya, maka Anda perlu mendapatkan stempel waktu terakhir dari file tersebut. Setelah Anda mengetahui panjangnya, Anda menghitung ukuran potongannya. Dengan ukuran ini Anda dapat membaca file dan memeriksa kapan Anda perlu memulai file baru   -  person XtremeBaumer    schedule 03.07.2018
comment
Mari kita melanjutkan diskusi ini dalam chat.   -  person user6250770    schedule 03.07.2018
comment
Mengapa menemukan kembali roda? Gunakan pustaka yang ada.   -  person rustyx    schedule 03.07.2018
comment
@rustyx dalam kode yang disediakan semuanya baik-baik saja, hanya saya perlu menghitung waktu dan membaginya menjadi beberapa bagian.   -  person user6250770    schedule 03.07.2018
comment
@XtremeBaumer memperbarui kode saya di sini. maaf atas repostnya   -  person user6250770    schedule 04.07.2018


Jawaban (2)


Saya telah menemukan cara untuk membagi file menjadi beberapa bagian,

    public static void main(String args[]) throws IOException {
String FilePath = "/Users/meh/Desktop/escapeplan.srt";
        FileInputStream fin = new FileInputStream(FilePath);

        System.out.println("size: " +fin.getChannel().size());
        long abc = 0l;
        abc = (fin.getChannel().size())/3;
        System.out.println("6: " +abc);
System.out.println("abc: " +abc);
       //FilePath = args[1];
        File filename = new File(FilePath);
        long splitFileSize = 0,bytefileSize=0;
        if (filename.exists()) {
            try {
                //bytefileSize = Long.parseLong(args[2]);
                splitFileSize = abc;
                Splitme spObj = new Splitme();
                spObj.split(FilePath, (long) splitFileSize);
                spObj = null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("File Not Found....");
        }
}
    public void split(String FilePath, long splitlen) {

            long leninfile = 0, leng = 0;
            int count = 1, data;
            try {
                File filename = new File(FilePath);
                InputStream infile = new BufferedInputStream(new FileInputStream(filename));
                data = infile.read();
                System.out.println("data");
                System.out.println(data);

                while (data != -1) {
                    filename = new File("/Users/meh/Documents/srt" + count + ".srt");
    //RandomAccessFile outfile = new RandomAccessFile(filename, "rw");

                    OutputStream outfile = new BufferedOutputStream(new FileOutputStream(filename));
                    while (data != -1 && leng < splitlen) {
                        outfile.write(data);
                        leng++;
                        data = infile.read();
                    }
                    leninfile += leng;
                    leng = 0;
                    outfile.close();
                    changeTimeStamp(filename, count);

                    count++;


                }
            } catch (Exception e) {
                e.printStackTrace();
            }
}
person user6250770    schedule 05.07.2018

Anda perlu mengurai file dua kali:

  • sekali untuk membaca waktu berakhir terakhir
  • kedua kalinya untuk memproses semua lini dan menghasilkan file keluaran.

    import java.io.BufferedWriter;
    import java.io.File;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.List;

    import org.apache.commons.io.FileUtils;

    public class SplitSRTFiles {

        /**
         * Splits a SRT file in multiple files each containing an equal time duration.
         * @param args
         * [0] number of wanted chunks
         * [1] source file name
         * @throws IOException
         */
        public static void main(String[] args) throws IOException {
            int nrOfChunks = Integer.parseInt(args[0]);
            File srtFile = new File(args[1]);
            System.out.println("Splitting "+srtFile.getAbsolutePath()+" into "+nrOfChunks+" files.");

            List<String> srcLines = FileUtils.readLines(srtFile);
            long fileEndTime = lastEndTime(srcLines);
            long msecsPerChunkFile = fileEndTime / nrOfChunks;
            int destFileCounter = 1;
            String[] fileNameParts = srtFile.getName().split("\\.");
            File outFile = new File(fileNameParts[0] + destFileCounter + "." + fileNameParts[1]);
            System.out.println("Writing to "+outFile.getAbsolutePath());
            outFile.createNewFile();
            FileWriter ofstream = new FileWriter(outFile);
            BufferedWriter out = new BufferedWriter(ofstream);

            for (String line : srcLines) {
                String[] atoms = line.split(" --> ");
                if (atoms.length > 1) {
                    long startTS = toMSec(atoms[0]);
                    // check if start time of this subtitle is after the current
                    // chunk
                    if (startTS > msecsPerChunkFile * destFileCounter) {
                        // close existing file ...
                        out.close();
                        ofstream.close();
                        // ... and start a new file
                        destFileCounter++;
                        outFile = new File(srtFile.getParent(), fileNameParts[0] + destFileCounter + "." + fileNameParts[1]);
                        System.out.println("Writing to "+outFile.getAbsolutePath());
                        outFile.createNewFile();
                        ofstream = new FileWriter(outFile);
                        out = new BufferedWriter(ofstream);
                    }
                }
                out.write(line + "/n");
            }
            out.close();
            ofstream.close();
            System.out.println("Done.");
        }

        /**
         * Calculates the time in msec of the end time of the last subtitle of the
         * file
         * 
         * @param lines
         *            read from file
         * @return end time in milliseconds of the last subtitle
         */
        public static long lastEndTime(List lines) throws IOException {
            String endTS = null;
            for (String line : lines) {
                String[] atoms = line.split(" --> ");
                if (atoms.length > 1) {
                    endTS = atoms[1];
                }
            }
            return endTS == null ? 0L : toMSec(endTS);
        }

        public static long toMSec(String time) {
            long tsMsec = 0;
            String atoms[] = time.split("\\,");
            if (atoms.length == 2) {
                tsMsec += Integer.parseInt(atoms[1]);
            }
            atoms = atoms[0].split(":");

            tsMsec += Integer.parseInt(atoms[2]) * 1000L; /* seconds */
            tsMsec += Integer.parseInt(atoms[1]) * 60000L; /* minutes */
            tsMsec += Integer.parseInt(atoms[0]) * 3600000L; /* hours */
            return tsMsec;
        }
    }
person Conffusion    schedule 03.07.2018
comment
Terima kasih. Tetapi saya mendapatkan kesalahan pada tipe for(String line: ) yang tidak kompatibel. objek yang diharapkan tetapi menemukan String. - person user6250770; 04.07.2018