<commit_before>package datastore

import (
	"encoding/json"
	"fmt"
	"github.com/grafov/m3u8"
	"log"
	"strconv"
	"time"
)

// struct Channel describes a broadcast channel
type Channel struct {
	Identifier      string // Identifier is the unique part of the redis key
	PlaybackCounter int64
	mediaPlaylist   *m3u8.MediaPlaylist
}

// function GetChannel retrieves Channel information from the datastore
// given a channel identifier. It returns the channel and any error
func GetChannel(channelId string) (rv *Channel, err error) {
	rv = &Channel{}
	rv.Identifier = channelId
	rv.PlaybackCounter, err = client.IncrBy(rv.PlaybackCounterKey(), 0).Result()
	rv.mediaPlaylist, _ = m3u8.NewMediaPlaylist(1000, 1000)
	return
}

func (c *Channel) PlaylistData() string {
	return c.mediaPlaylist.Encode().String()
}

func (c Channel) CurrentItem() (PlaylistItem, error) {
	jsonString, err := client.LIndex(c.PlaybackQueueKey(), 0).Result()
	if err != nil {
		return PlaylistItem{}, err
	}

	item := PlaylistItem{}
	if err := json.Unmarshal([]byte(jsonString), &item); err != nil {
		return PlaylistItem{}, err
	}

	return item, nil
}

func (c Channel) PushItem(i *PlaylistItem) error {
	jsonBytes, err := json.Marshal(i)
	if err != nil {
		return err
	}

	err = client.RPush(c.PlaybackQueueKey(), string(jsonBytes)).Err()
	return err
}

// function AdvanceCounter advances the playback counter, and updates the datastore
func (c *Channel) AdvanceCounter() error {
	currentItem, err := c.CurrentItem()
	if err != nil {
		return err
	}

	if currentItem.StartAt > c.PlaybackCounter {
		c.PlaybackCounter = currentItem.StartAt
	}
	videoFile := fmt.Sprintf(currentItem.URLFormat, c.PlaybackCounter)
	if err := c.mediaPlaylist.Append(videoFile, 5.0, ""); err != nil {
		log.Println("Error appending item to playlist:", err)
		c.mediaPlaylist.Slide(videoFile, 5.0, "")
	}
	c.PlaybackCounter = c.PlaybackCounter + 1

	if c.PlaybackCounter > currentItem.EndAt {
		c.ResetCounter()
		if !currentItem.Loop {
			client.LPop(c.PlaybackQueueKey())
		}
	}<commit_msg>add discontinuity when switching media files<commit_after>package datastore

import (
	"encoding/json"
	"fmt"
	"github.com/grafov/m3u8"
	"log"
	"strconv"
	"time"
)

// struct Channel describes a broadcast channel
type Channel struct {
	Identifier      string // Identifier is the unique part of the redis key
	PlaybackCounter int64
	mediaPlaylist   *m3u8.MediaPlaylist
}

// function GetChannel retrieves Channel information from the datastore
// given a channel identifier. It returns the channel and any error
func GetChannel(channelId string) (rv *Channel, err error) {
	rv = &Channel{}
	rv.Identifier = channelId
	rv.PlaybackCounter, err = client.IncrBy(rv.PlaybackCounterKey(), 0).Result()
	rv.mediaPlaylist, _ = m3u8.NewMediaPlaylist(1000, 1000)
	return
}

func (c *Channel) PlaylistData() string {
	return c.mediaPlaylist.Encode().String()
}

func (c Channel) CurrentItem() (PlaylistItem, error) {
	jsonString, err := client.LIndex(c.PlaybackQueueKey(), 0).Result()
	if err != nil {
		return PlaylistItem{}, err
	}

	item := PlaylistItem{}
	if err := json.Unmarshal([]byte(jsonString), &item); err != nil {
		return PlaylistItem{}, err
	}

	return item, nil
}

func (c Channel) PushItem(i *PlaylistItem) error {
	jsonBytes, err := json.Marshal(i)
	if err != nil {
		return err
	}

	err = client.RPush(c.PlaybackQueueKey(), string(jsonBytes)).Err()
	return err
}

// function AdvanceCounter advances the playback counter, and updates the datastore
func (c *Channel) AdvanceCounter() error {
	currentItem, err := c.CurrentItem()
	if err != nil {
		return err
	}

	if currentItem.StartAt > c.PlaybackCounter {
		c.PlaybackCounter = currentItem.StartAt
	}
	videoFile := fmt.Sprintf(currentItem.URLFormat, c.PlaybackCounter)
	if err := c.mediaPlaylist.Append(videoFile, 5.0, ""); err != nil {
		log.Println("Error appending item to playlist:", err)
		c.mediaPlaylist.Slide(videoFile, 5.0, "")
	}
	c.PlaybackCounter = c.PlaybackCounter + 1

	if c.PlaybackCounter > currentItem.EndAt {
		c.ResetCounter()
		if !currentItem.Loop {
			if err := c.mediaPlaylist.SetDiscontinuity(); err != nil {
				log.Println("Error setting discontinuity:", err)
			}
			client.LPop(c.PlaybackQueueKey())
		}
	}
{'fraction_non_alphanumeric': 0.12420306965761511, 'fraction_numerical': 0.010861865407319952, 'mean_word_length': 4.3893129770992365, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '470094', 'n_tokens_mistral': 1487, 'n_tokens_neox': 1408, 'n_words': 378}