代码拉取完成,页面将自动刷新
// Copyright 2019 The ebml-go authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"encoding/binary"
"fmt"
"net"
"os"
"os/signal"
"gitee.com/general252/ebml-go/webm"
)
func main() {
w, err := os.OpenFile("test.webm", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
if err != nil {
panic(err)
}
ws, err := webm.NewSimpleBlockWriter(w,
[]webm.TrackEntry{
{
Name: "Video",
TrackNumber: 1,
TrackUID: 12345,
CodecID: "V_VP8",
TrackType: 1,
DefaultDuration: 33333333,
Video: &webm.Video{
PixelWidth: 320,
PixelHeight: 240,
},
},
})
if err != nil {
panic(err)
}
fmt.Print("Run following command to send RTP stream to this example:\n" +
"$ gst-launch-1.0 videotestsrc" +
" ! video/x-raw,width=320,height=240,framerate=30/1" +
" ! vp8enc target-bitrate=4000" +
" ! rtpvp8pay ! udpsink host=localhost port=4000\n\n" +
"Waiting first keyframe...\n")
// Listen UDP RTP packets
addr, err := net.ResolveUDPAddr("udp", ":4000")
if err != nil {
panic(err)
}
pc, err := net.ListenUDP("udp", addr)
if err != nil {
panic(err)
}
closed := make(chan os.Signal, 1)
signal.Notify(closed, os.Interrupt)
go func() {
<-closed
pc.Close()
}()
var frame []byte
var keyframe bool
var keyframeCnt int
var tcRawLast int64 = -1
var tcRawBase int64
buffer := make([]byte, 1522)
for {
n, _, err := pc.ReadFrom(buffer)
if err != nil {
fmt.Println(err)
break
}
if n < 14 {
fmt.Print("RTP packet size is too small.\n")
continue
}
// RTP descriptor and header must be fully parsed in the real application.
vp8Desc := buffer[12]
// *Extended control bits present flag* is not supported in this example
if vp8Desc&0x80 != 0 {
panic("Incoming VP8 payload descriptor has extended fields which is not supported by this example!")
}
// *Start of VP8 partition flag*
if vp8Desc&0x10 != 0 {
if keyframe {
keyframeCnt++
}
if len(frame) > 0 && keyframeCnt > 0 {
tcRaw := int64(binary.BigEndian.Uint32(buffer[4:8]))
if tcRawLast == -1 {
tcRawLast = tcRaw
}
if tcRaw < 0x10000 && tcRawLast > 0xFFFFFFFF-0x10000 {
// counter overflow
tcRawBase += 0x100000000
} else if tcRawLast < 0x10000 && tcRaw > 0xFFFFFFFF-0x10000 {
// counter underflow
tcRawBase -= 0x100000000
}
tcRawLast = tcRaw
tc := (tcRaw + tcRawBase) / 90 // VP8 timestamp rate is 90000.
fmt.Printf("RTP frame received. (len: %d, timestamp: %d, keyframe: %v)\n", len(frame), tc, keyframe)
ws[0].Write(keyframe, int64(tc), frame)
}
frame = []byte{}
keyframe = false
// RTP header 12 bytes, VP8 payload descriptor 1 byte.
vp8Header := buffer[13]
if vp8Header&0x01 == 0 {
keyframe = true
}
}
frame = append(frame, buffer[13:n]...)
}
fmt.Printf("\nFinalizing webm...\n")
ws[0].Close()
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。