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

com.iheartradio.m3u8.PlaylistWriter Maven / Gradle / Ivy

package com.iheartradio.m3u8;

import java.io.IOException;
import java.io.OutputStream;

import com.iheartradio.m3u8.data.Playlist;

import static com.iheartradio.m3u8.Constants.UTF_8_BOM_BYTES;

public class PlaylistWriter {
    private final Writer mWriter;
    private final OutputStream mOutputStream;
    private final boolean mShouldWriteByteOrderMark;

    private boolean mFirstWrite = true;

    /**
     * This writes the given Playlist to the given OutputStream with a prepended BOM (Byte Order Mark).
     * This exists for convenience if you absolutely need a BOM.
     * From the specification: "They (playlist files) MUST NOT contain any byte order mark (BOM); Clients SHOULD reject Playlists which contain a BOM..."
     *
     * @param outputStream OutputStream playlists will be written to
     * @param format format in which to write the playlist
     * @param encoding encoding in which to write the playlist
     */
    public PlaylistWriter(OutputStream outputStream, Format format, Encoding encoding) {
        this(outputStream, format, encoding, false);
    }

    private PlaylistWriter(OutputStream outputStream, Format format, Encoding encoding, boolean useByteOrderMark) {
        if (outputStream == null) {
            throw new IllegalArgumentException("outputStream is null");
        }

        if (format == null) {
            throw new IllegalArgumentException("format is null");
        }

        if (encoding == null) {
            throw new IllegalArgumentException("encoding is null");
        }

        mOutputStream = outputStream;
        mShouldWriteByteOrderMark = encoding.supportsByteOrderMark && useByteOrderMark;

        switch (format) {
            case M3U:
                mWriter = new M3uWriter(outputStream, encoding);
                break;
            case EXT_M3U:
                mWriter = new ExtendedM3uWriter(outputStream, encoding);
                break;
            default:
                throw new RuntimeException("unsupported format detected, this should be impossible: " + format);
        }
    }

    /**
     * Writes the given Playlist to the contained OutputStream.
     *
     * @throws IOException
     * @throws ParseException if the data is improperly formatted
     * @throws PlaylistException if the representation of the playlist is invalid,
     *                           that is, if PlaylistValidation.from(playlist).isValid() == false
     */
    public void write(Playlist playlist) throws IOException, ParseException, PlaylistException {
        final PlaylistValidation validation = PlaylistValidation.from(playlist);

        if (!validation.isValid()) {
            throw new PlaylistException("", validation.getErrors());
        }

        writeByteOrderMark();
        mWriter.write(playlist);
        mFirstWrite = false;
    }

    private void writeByteOrderMark() throws IOException {
        if (mShouldWriteByteOrderMark && mFirstWrite) {
            for (int i = 0; i < UTF_8_BOM_BYTES.length; ++i) {
                mOutputStream.write(UTF_8_BOM_BYTES[i]);
            }
        }
    }

    public static class Builder {
        private OutputStream mOutputStream;
        private Format mFormat;
        private Encoding mEncoding;
        private boolean mUseByteOrderMark;

        /**
         * @param outputStream OutputStream playlists will be written to
         */
        public Builder withOutputStream(OutputStream outputStream) {
            mOutputStream = outputStream;
            return this;
        }

        /**
         * @param format format in which to write the playlist
         */
        public Builder withFormat(Format format) {
            mFormat = format;
            return this;
        }

        /**
         * @param encoding encoding in which to write the playlist
         */
        public Builder withEncoding(Encoding encoding) {
            mEncoding = encoding;
            return this;
        }

        /**
         * When using a BOM, the first call to write will prepend the BOM character to the playlist. Subsequent
         * calls to write will not prepend the BOM to support writing multiple ENDLIST delimited playlists.
         *
         * @deprecated The specification explicitly says that playlists MUST NOT contain a byte order mark (BOM)
         */
        public Builder useByteOrderMark() {
            mUseByteOrderMark = true;
            return this;
        }

        public PlaylistWriter build() {
            return new PlaylistWriter(mOutputStream, mFormat, mEncoding, mUseByteOrderMark);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy