progressbar icon indicating copy to clipboard operation
progressbar copied to clipboard

Doesn't stream content to the file.

Open AYehia0 opened this issue 3 years ago • 2 comments

Hello, excuse my question I am still a beginner in go :smile: I am trying to stream the segments of the m3u8 into one file by appending to the file created, but unfortunately it's doesn't and returns empty file.

// extract the urls of the individual segment and then steam/download.
func downloadSeg(wg *sync.WaitGroup, segment *m.MediaSegment, file *os.File, dlbar *bar.ProgressBar) {
	defer wg.Done()
	resp, err := http.Get(segment.URI)

	log.Println("Error : ", resp.StatusCode)
	if err != nil {
		log.Println("Error : ", err)
		return
	}

	defer resp.Body.Close()

	// append to the file
	_, err = io.Copy(io.MultiWriter(file, dlbar), resp.Body)

	if err != nil {
		log.Println("Error : ", err)
		return
	}

}

// using the goroutine to download each segment concurrently and wait till all finished
func downloadM3u8(m3u8Url string, filepath string) error {
	resp, err := http.Get(m3u8Url)

	if err != nil {
		return err
	}
	defer resp.Body.Close()

	pl, listType, err := m.DecodeFrom(resp.Body, true)
	if err != nil {
		return err
	}
	dlbar := bar.DefaultBytes(resp.ContentLength, "Downloading")
	// create a file to add content to
	// file, _ := os.OpenFile(filepath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
	file, _ := os.Create(filepath)

	// the go routine now
	var wg sync.WaitGroup
	switch listType {
	case m.MEDIA:
		mediapl := pl.(*m.MediaPlaylist)
		for _, segment := range mediapl.Segments {
			if segment == nil {
				continue
			}
			wg.Add(1)
			go downloadSeg(&wg, segment, file, dlbar)
		}
	default:
		return errors.New("Unsupported type!")
	}

	return nil
}

I call downloadM3u8(track.Url, path) after that.

AYehia0 avatar Jan 11 '23 13:01 AYehia0

for some reasons removing the go keyword before the downloadSeg solves the problem, IDK why lol.

AYehia0 avatar Jan 11 '23 14:01 AYehia0

I think you missed calling wg.Wait() in the end. hence , program is exiting even before all go routines are done. adding wg.Wait() before return nil, will help I guess.

WheeskyJack avatar Dec 10 '23 06:12 WheeskyJack