server-sdk-go icon indicating copy to clipboard operation
server-sdk-go copied to clipboard

Audio file is cropped from the beginning

Open vkuptcov opened this issue 1 year ago • 4 comments

I created a very simple server that sends ogg OPUS audio files to web clients.

	room, err := lksdk.ConnectToRoom(os.Getenv("LIVEKIT_URL"), lksdk.ConnectInfo{
		APIKey:              os.Getenv("LIVEKIT_API_KEY"),
		APISecret:           os.Getenv("LIVEKIT_API_SECRET"),
		RoomName:            roomName,
		ParticipantIdentity: "local",
	}, &lksdk.RoomCallback{})
	if err != nil {
		log.Fatal("cannot connect to room:", err)
		return err
	}

	track, err := lksdk.NewLocalFileTrack(file,
		lksdk.ReaderTrackWithMime(webrtc.MimeTypeOpus),
		lksdk.ReaderTrackWithOnWriteComplete(func() { fmt.Println("track finished") }),
	)
	if err != nil {
		log.Fatal("cannot create track:", err)
		return err
	}

	res, err := room.LocalParticipant.PublishTrack(track, &lksdk.TrackPublicationOptions{
		Name: file,
	})

	if err != nil {
		log.Fatal("cannot publish track:", err)
		return err
	}

Basically, I did everything as described here https://github.com/livekit/server-sdk-go?tab=readme-ov-file#publishing-tracks-to-room adapting only to audio files. In about 90% of the cases, the first second or even several seconds are missed and I don't hear them on the client side. It should be possible to somehow make sure that all clients subscribed to the track before publishing it.

vkuptcov avatar Apr 02 '24 22:04 vkuptcov

This is a bit tricky due to the subscription lifecycle. the current logic in NewLocalReaderTrack is to start writing the file as soon as the track is considered published:

	track.OnBind(func() {
		if err := track.StartWrite(provider, provider.OnWriteComplete); err != nil {
			logger.Errorw("Could not start writing", err)
		}
	})

There isn't really a way to know when all of the the subscribers have subscribed to the track.. but I think you can modify this function to do the following:

  1. construct an empty opus packet: see here for an example
  2. write it with track.WriteRTP, this lets server complete the publication process
  3. sleep for a few seconds to give subscribers time to subscribe
  4. then call track.StartWrite

davidzhao avatar Apr 03 '24 07:04 davidzhao

Thank you, @davidzhao ! I've tested the idea and it looks like it's the way to go

vkuptcov avatar Apr 03 '24 14:04 vkuptcov

Is there a ready-to-use method to publish an audio file without missing the beginning parts? It's quite strange that this is an issue in such a large streaming ecosystem. Specifically, my case is 1-to-1 prerecorded audio file streaming

denis-obukhov avatar Jun 28 '24 11:06 denis-obukhov