Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example of creating webm from webp #175

Open
LazarenkoA opened this issue Dec 21, 2022 · 8 comments
Open

example of creating webm from webp #175

LazarenkoA opened this issue Dec 21, 2022 · 8 comments
Labels
question Further information is requested

Comments

@LazarenkoA
Copy link

I have frames (webp files) I want to create a webm video out of them can I do it using your code?

@LazarenkoA
Copy link
Author

LazarenkoA commented Dec 21, 2022

or from image.Image

@at-wat
Copy link
Owner

at-wat commented Dec 22, 2022

Creating WebM video from images basically requires:

  1. parse images
  2. encode images to a video by VP8 or VP9 codec
  3. store encoded video as WebM

This package handles 3, and you need to write 1 and 2.

@at-wat at-wat added the question Further information is requested label Dec 22, 2022
@LazarenkoA
Copy link
Author

to convert image to webp i use github.com/chai2010/webp but when i start to write frames to video, the video then doesn't play.

I can show the code if you want

@LazarenkoA
Copy link
Author

it turned out to convert to vp8 (I used another converter), the video is played on the front (via WebRTC), how to use your package to get the video, I can't figure out. I would like an example that periodically takes an array of bytes and writes them to a file

@at-wat
Copy link
Owner

at-wat commented Dec 27, 2022

You can check https://github.com/pion/example-webrtc-applications/tree/master/save-to-webm if encoding part is done

@LazarenkoA
Copy link
Author

LazarenkoA commented Dec 27, 2022

I was guided by this example, but since PushVP8 does not accept an array of bytes, I call it like this

w.PushVP8(&rtp.Packet{Payload: data	})

where data is an array of bytes, but on the line
sample := s.videoBuilder.Pop() sample is always equal to nil

func newWebmSaver() *webmSaver {
	return &webmSaver{
		videoBuilder: samplebuilder.New(10, &codecs.VP8Packet{}, 90000),
	}
}
func (s *webmSaver) InitWriter(width, height int) webm.BlockWriteCloser {
	w, err := os.OpenFile("/Users/20128315/Documents/GIT/screenRecorder/test.webm", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
	if err != nil {
		panic(err)
	}

	ws, err := webm.NewSimpleBlockWriter(w,
		[]webm.TrackEntry{
			{
				Name:            "Video",
				TrackNumber:     2,
				TrackUID:        67890,
				CodecID:         "V_VP8",
				TrackType:       1,
				DefaultDuration: 33333333,
				Video: &webm.Video{
					PixelWidth:  uint64(width),
					PixelHeight: uint64(height),
				},
			},
		})
	if err != nil {
		panic(err)
	}
	fmt.Printf("WebM saver has started with video width=%d, height=%d\n", width, height)

	return ws[0]
}
func (s *webmSaver) Close() {
	fmt.Printf("Finalizing webm...\n")
	if s.videoWriter != nil {
		if err := s.videoWriter.Close(); err != nil {
			panic(err)
		}
	}
}
func (s *webmSaver) PushVP8(rtpPacket *rtp.Packet) {
	s.videoBuilder.Push(rtpPacket)

	for {
		sample := s.videoBuilder.Pop()
		if sample == nil {
			return
		}
		// Read VP8 header.
		videoKeyframe := (sample.Data[0]&0x1 == 0)
		if videoKeyframe {
			// Keyframe has frame information.
			raw := uint(sample.Data[6]) | uint(sample.Data[7])<<8 | uint(sample.Data[8])<<16 | uint(sample.Data[9])<<24
			width := int(raw & 0x3FFF)
			height := int((raw >> 16) & 0x3FFF)

			if s.videoWriter == nil {
				// Initialize WebM saver using received frame size.
				s.InitWriter(width, height)
			}
		}
		if s.videoWriter != nil {
			s.videoTimestamp += sample.Duration
			if _, err := s.videoWriter.Write(videoKeyframe, int64(s.videoTimestamp/time.Millisecond), sample.Data); err != nil {
				panic(err)
			}
		}
	}
}

@at-wat
Copy link
Owner

at-wat commented Dec 27, 2022

samplebuilder.SampleBuilder is a class to reconstruct frames from partitioned RTP packets, and it requires RTP sequence number and timestamp.
As you already have frames without partitioning, you need to unuse SampleBuilder.

@LazarenkoA
Copy link
Author

full story:
a stream of bytes comes from one application (screen agent) to the screen server. Task of the screen server is to send them to the front via webrtc and write them to a file (so that you can view it later), but this does not work with writing to a file, tell me, can your package be used to solve this problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants