func DecodeAttributeList(line string) map[string]string {
	return decodeParamsLine(line)
}
DecodeAttributeList turns an attribute list into a key, value map. You should trim
any characters not part of the attribute list, such as the tag and ':'.
package m3u8
import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"regexp"
	"strconv"
	"strings"
	"time"
)
var reKeyValue = regexp.MustCompile(`([a-zA-Z0-9_-]+)=("[^"]+"|[^",]+)`)
var TimeParse func(value string) (time.Time, error) = FullTimeParse
func (p *MasterPlaylist) Decode(data bytes.Buffer, strict bool) error {
	return p.decode(&data, strict)
}
func (p *MasterPlaylist) DecodeFrom(reader io.Reader, strict bool) error {
	buf := new(bytes.Buffer)
	_, err := buf.ReadFrom(reader)
	if err != nil {
		return err
	}
	return p.decode(buf, strict)
}
func (p *MasterPlaylist) WithCustomDecoders(customDecoders []CustomDecoder) Playlist {
	if p.Custom == nil {
		p.Custom = make(map[string]CustomTag)
	}
	p.customDecoders = customDecoders
	return p
}
func (p *MasterPlaylist) decode(buf *bytes.Buffer, strict bool) error {
	var eof bool
	state := new(decodingState)
	for !eof {
		line, err := buf.ReadString('\n')
		if err == io.EOF {
			eof = true
		} else if err != nil {
			break
		}
		err = decodeLineOfMasterPlaylist(p, state, line, strict)
		if strict && err != nil {
			return err
		}
	}
	if strict && !state.m3u {
		return errors.New("#EXTM3U absent")
	}
	return nil
}
func (p *MediaPlaylist) Decode(data bytes.Buffer, strict bool) error {
	return p.decode(&data, strict)
}
func (p *MediaPlaylist) DecodeFrom(reader io.Reader, strict bool) error {
	buf := new(bytes.Buffer)
	_, err := buf.ReadFrom(reader)
	if err != nil {
		return err
	}
	return p.decode(buf, strict)
}
func (p *MediaPlaylist) WithCustomDecoders(customDecoders []CustomDecoder) Playlist {
	if p.Custom == nil {
		p.Custom = make(map[string]CustomTag)
	}
	p.customDecoders = customDecoders
	return p
}
func (p *MediaPlaylist) decode(buf *bytes.Buffer, strict bool) error {
	var eof bool
	var line string
	var err error
	state := new(decodingState)
	wv := new(WV)
	for !eof {
		if line, err = buf.ReadString('\n'); err == io.EOF {
			eof = true
		} else if err != nil {
			break
		}
		err = decodeLineOfMediaPlaylist(p, wv, state, line, strict)
		if strict && err != nil {
			return err
		}
	}
	if state.tagWV {
		p.WV = wv
	}
	if strict && !state.m3u {
		return errors.New("#EXTM3U absent")
	}
	return nil
}
func Decode(data bytes.Buffer, strict bool) (Playlist, ListType, error) {
	return decode(&data, strict, nil)
}
func DecodeFrom(reader io.Reader, strict bool) (Playlist, ListType, error) {
	buf := new(bytes.Buffer)
	_, err := buf.ReadFrom(reader)
	if err != nil {
		return nil, 0, err
	}
	return decode(buf, strict, nil)
}
func DecodeWith(input interface{}, strict bool, customDecoders []CustomDecoder) (Playlist, ListType, error) {
	switch v := input.(type) {
	case bytes.Buffer:
		return decode(&v, strict, customDecoders)
	case io.Reader:
		buf := new(bytes.Buffer)
		_, err := buf.ReadFrom(v)
		if err != nil {
			return nil, 0, err
		}
		return decode(buf, strict, customDecoders)
	default:
		return nil, 0, errors.New("input must be bytes.Buffer or io.Reader type")
	}
}
func decode(buf *bytes.Buffer, strict bool, customDecoders []CustomDecoder) (Playlist, ListType, error) {
	var eof bool
	var line string
	var master *MasterPlaylist
	var media *MediaPlaylist
	var listType ListType
	var err error
	state := new(decodingState)
	wv := new(WV)
	master = NewMasterPlaylist()
	media, err = NewMediaPlaylist(8, 1024)  
	if err != nil {
		return nil, 0, fmt.Errorf("Create media playlist failed: %s", err)
	}
	if customDecoders != nil {
		media = media.WithCustomDecoders(customDecoders).(*MediaPlaylist)
		master = master.WithCustomDecoders(customDecoders).(*MasterPlaylist)
		state.custom = make(map[string]CustomTag)
	}
	for !eof {
		if line, err = buf.ReadString('\n'); err == io.EOF {
			eof = true
		} else if err != nil {
			break
		}
		if len(line) < 1 || line == "\r" {
			continue
		}
		err = decodeLineOfMasterPlaylist(master, state, line, strict)
		if strict && err != nil {
			return master, state.listType, err
		}
		err = decodeLineOfMediaPlaylist(media, wv, state, line, strict)
		if strict && err != nil {
			return media, state.listType, err
		}
	}
	if state.listType == MEDIA && state.tagWV {
		media.WV = wv
	}
	if strict && !state.m3u {
		return nil, listType, errors.New("#EXTM3U absent")
	}
	switch state.listType {
	case MASTER:
		return master, MASTER, nil
	case MEDIA:
		if media.Closed || media.MediaType == EVENT {
			media.SetWinSize(0)
		}
		return media, MEDIA, nil
	}
	return nil, state.listType, errors.New("Can't detect playlist type")
}