mirror of https://bitbucket.org/ausocean/av.git
Merged in single-frame-h264 (pull request #108)
av: allow for single h264 frame streaming Approved-by: kortschak <dan@kortschak.io>
This commit is contained in:
commit
a76be1fd5b
|
@ -30,10 +30,10 @@ LICENSE
|
||||||
package rtmp
|
package rtmp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -203,25 +203,27 @@ func TestFromFrame(t *testing.T) {
|
||||||
t.Errorf("Session.Open failed with error: %v", err)
|
t.Errorf("Session.Open failed with error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadFile(filepath.Join(testDataDir, "AusOcean_logo_1080p.h264"))
|
testFrame := os.Getenv("RTMP_TEST_FRAME")
|
||||||
|
b, err := ioutil.ReadFile(testFrame)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("ReadFile failed with error: %v", err)
|
t.Errorf("ReadFile failed with error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass RTMP session, true for audio, true for video, and 25 FPS
|
const noOfFrames = 1000
|
||||||
// ToDo: fix this. Although we can encode the file and YouTube
|
videoData := make([]byte, 0, noOfFrames*len(b))
|
||||||
// doesn't complain, YouTube doesn't play it (even when we
|
for i := 0; i < noOfFrames; i++ {
|
||||||
// send 1 minute's worth).
|
videoData = append(videoData, b...)
|
||||||
flvEncoder, err := flv.NewEncoder(s, true, true, 25)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("failed to create encoder: %v", err)
|
|
||||||
}
|
}
|
||||||
for i := 0; i < 25; i++ {
|
|
||||||
err := flvEncoder.Encode(b)
|
const frameRate = 25
|
||||||
|
rs := &rtmpSender{s: s}
|
||||||
|
flvEncoder, err := flv.NewEncoder(rs, true, true, frameRate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Encoding failed with error: %v", err)
|
t.Errorf("Failed to create flv encoder with error: %v", err)
|
||||||
}
|
}
|
||||||
time.Sleep(time.Millisecond / 25) // rate limit to 1/25s
|
err = lex.H264(flvEncoder, bytes.NewReader(videoData), time.Second/time.Duration(frameRate))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Lexing failed with error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Close()
|
err = s.Close()
|
||||||
|
@ -230,6 +232,18 @@ func TestFromFrame(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type rtmpSender struct {
|
||||||
|
s *Session
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rs *rtmpSender) Write(p []byte) (int, error) {
|
||||||
|
n, err := rs.s.Write(p)
|
||||||
|
if err != errTinyPacket && err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
// TestFromFile tests streaming from an video file comprising raw H.264.
|
// TestFromFile tests streaming from an video file comprising raw H.264.
|
||||||
// The test file is supplied via the RTMP_TEST_FILE environment variable.
|
// The test file is supplied via the RTMP_TEST_FILE environment variable.
|
||||||
func TestFromFile(t *testing.T) {
|
func TestFromFile(t *testing.T) {
|
||||||
|
|
|
@ -119,10 +119,11 @@ outer:
|
||||||
const (
|
const (
|
||||||
nonIdrPic = 1
|
nonIdrPic = 1
|
||||||
idrPic = 5
|
idrPic = 5
|
||||||
|
suppEnhInfo = 6
|
||||||
paramSet = 8
|
paramSet = 8
|
||||||
)
|
)
|
||||||
switch nalTyp := b & 0x1f; nalTyp {
|
switch nalTyp := b & 0x1f; nalTyp {
|
||||||
case nonIdrPic, idrPic, paramSet:
|
case nonIdrPic, idrPic, paramSet, suppEnhInfo:
|
||||||
writeOut = true
|
writeOut = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue