All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.alexeylapin.m3u8.parser.AbstractPlaylistParser Maven / Gradle / Ivy

The newest version!
package com.github.alexeylapin.m3u8.parser;

import com.github.alexeylapin.m3u8.model.Playlist;
import com.github.alexeylapin.m3u8.model.Playlist;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;

import static java.nio.charset.StandardCharsets.UTF_8;

public abstract class AbstractPlaylistParser {
    private static final String EXTM3U = "#EXTM3U";

    public T readPlaylist(InputStream inputStream) throws IOException {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, UTF_8))) {
            return readPlaylist(reader);
        }
    }

    public T readPlaylist(Path path) throws IOException {
        try (BufferedReader reader = Files.newBufferedReader(path, UTF_8)) {
            return readPlaylist(reader);
        }
    }

    public T readPlaylist(BufferedReader bufferedReader) throws PlaylistParserException {
        Iterator lineIterator = new Iterator() {
            String nextLine = null;

            @Override
            public boolean hasNext() {
                if (nextLine != null) {
                    return true;
                } else {
                    try {
                        nextLine = bufferedReader.readLine();
                        return (nextLine != null);
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                }
            }

            @Override
            public String next() {
                if (nextLine != null || hasNext()) {
                    String line = nextLine;
                    nextLine = null;
                    return line;
                } else {
                    throw new NoSuchElementException();
                }
            }
        };

        return readPlaylist(lineIterator);
    }

    public T readPlaylist(String string) throws PlaylistParserException {
        return readPlaylist(new BufferedReader(new StringReader(string)));
    }

    public T readPlaylist(Iterator lineIterator) throws PlaylistParserException {
        // All playlists must start with the tag #EXTM3U. According to the RFC this must be on the first line,
        // but some examples allow empty lines before the tag.
        boolean extM3uFound = false;
        while (lineIterator.hasNext() && !extM3uFound) {
            String line = lineIterator.next();
            if (EXTM3U.equals(line)) {
                extM3uFound = true;
            } else if (!line.isEmpty()) {
                break; // invalid line  found
            }
            // else: line is empty
        }
        if (!extM3uFound) {
            throw new PlaylistParserException("Invalid playlist. Expected #EXTM3U.");
        }

        final B builder = newBuilder();

        while (lineIterator.hasNext()) {
            String line = lineIterator.next();

            if (line.startsWith("#EXT")) {
                int colonPosition = line.indexOf(':');
                String prefix = colonPosition > 0 ? line.substring(1, colonPosition) : line.substring(1);
                String attributes = colonPosition > 0 ? line.substring(colonPosition + 1) : "";

                onTag(builder, prefix, attributes, lineIterator);
            } else if (!line.isEmpty()) {
                if (line.startsWith("#")) {
                    onComment(builder, line.substring(1));
                } else {
                    onURI(builder, line); // <-- TODO silly?
                }
            }
        }

        return build(builder);
    }

    abstract B newBuilder();

    abstract void onTag(B builder, String prefix, String attributes, Iterator lineIterator) throws PlaylistParserException;

    abstract void onComment(B builder, String value);

    void onURI(B builder, String uri) throws PlaylistParserException {
        throw new PlaylistParserException("Unexpected URI in playlist: " + uri);
    }

    abstract T build(B builder);

    abstract void write(T playlist, TextBuilder textBuilder);

    public String writePlaylistAsString(T playlist) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(EXTM3U).append('\n');

        TextBuilder textBuilder = new TextBuilder(stringBuilder);

        for (String comment : playlist.comments()) {
            if (!comment.startsWith("EXT")) {
                textBuilder.add("#").add(comment).add("\n");
            }
        }

        write(playlist, textBuilder);
        return stringBuilder.toString();
    }

    public byte[] writePlaylistAsBytes(T playlist) {
        return writePlaylistAsString(playlist).getBytes(UTF_8);
    }

    public ByteBuffer writePlaylistAsByteBuffer(T playlist) {
        return ByteBuffer.wrap(writePlaylistAsBytes(playlist));
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy