Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
chigusa committed Apr 2, 2019
2 parents 05c2720 + 65fb94f commit d5e5057
Show file tree
Hide file tree
Showing 15 changed files with 655 additions and 63 deletions.
36 changes: 29 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ BUILD_TIME=$(shell date '+%Y-%m-%d_%H:%M:%S')
GIT_HASH=$(shell git rev-parse HEAD)
CONSTS_PATH=github.com/hr3lxphr6j/bililive-go/src/consts
LD_FLAGS=-ldflags '-s -w -X ${CONSTS_PATH}.BuildTime=${BUILD_TIME} -X ${CONSTS_PATH}.AppVersion=${VERSION} -X ${CONSTS_PATH}.GitHash=${GIT_HASH}'
UPX=1

.PHONY: all
all: mkdir
Expand Down Expand Up @@ -34,37 +35,58 @@ release-all-platform: release-darwin-amd64 \
.PHONY: release-darwin-amd64
release-darwin-amd64: mkdir
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build ${LD_FLAGS} -o ${BIN_PATH}/${BIN_NAME}-darwin-amd64
upx --no-progress ${BIN_PATH}/${BIN_NAME}-darwin-amd64
@if [ ${UPX} -eq 1 ]; \
then \
upx --no-progress ${BIN_PATH}/${BIN_NAME}-darwin-amd64; \
fi

.PHONY: release-linux-386
release-linux-386: mkdir
CGO_ENABLED=0 GOOS=linux GOARCH=386 go build ${LD_FLAGS} -o ${BIN_PATH}/${BIN_NAME}-linux-386
upx --no-progress ${BIN_PATH}/${BIN_NAME}-linux-386
@if [ ${UPX} -eq 1 ]; \
then \
upx --no-progress ${BIN_PATH}/${BIN_NAME}-linux-386; \
fi

.PHONY: release-linux-amd64
release-linux-amd64: mkdir
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ${LD_FLAGS} -o ${BIN_PATH}/${BIN_NAME}-linux-amd64
upx --no-progress ${BIN_PATH}/${BIN_NAME}-linux-amd64
@if [ ${UPX} -eq 1 ]; \
then \
upx --no-progress ${BIN_PATH}/${BIN_NAME}-linux-amd64; \
fi

.PHONY: release-linux-arm
release-linux-arm: mkdir
CGO_ENABLED=0 GOOS=linux GOARCH=arm go build ${LD_FLAGS} -o ${BIN_PATH}/${BIN_NAME}-linux-arm
upx --no-progress ${BIN_PATH}/${BIN_NAME}-linux-arm
@if [ ${UPX} -eq 1 ]; \
then \
upx --no-progress ${BIN_PATH}/${BIN_NAME}-linux-arm; \
fi

.PHONY: release-linux-arm64
release-linux-arm64: mkdir
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build ${LD_FLAGS} -o ${BIN_PATH}/${BIN_NAME}-linux-arm64
upx --no-progress ${BIN_PATH}/${BIN_NAME}-linux-arm64
@if [ ${UPX} -eq 1 ]; \
then \
upx --no-progress ${BIN_PATH}/${BIN_NAME}-linux-arm64; \
fi

.PHONY: release-windows-386
release-windows-386: mkdir
CGO_ENABLED=0 GOOS=windows GOARCH=386 go build ${LD_FLAGS} -o ${BIN_PATH}/${BIN_NAME}-windows-386.exe
upx --no-progress ${BIN_PATH}/${BIN_NAME}-windows-386.exe
@if [ ${UPX} -eq 1 ]; \
then \
upx --no-progress ${BIN_PATH}/${BIN_NAME}-windows-386.exe; \
fi

.PHONY: release-windows-amd64
release-windows-amd64: mkdir
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build ${LD_FLAGS} -o ${BIN_PATH}/${BIN_NAME}-windows-amd64.exe
upx --no-progress ${BIN_PATH}/${BIN_NAME}-windows-amd64.exe
@if [ ${UPX} -eq 1 ]; \
then \
upx --no-progress ${BIN_PATH}/${BIN_NAME}-windows-amd64.exe; \
fi

.PHONY: release-docker
release-docker: release-linux-amd64
Expand Down
2 changes: 2 additions & 0 deletions config.docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ rpc:
debug: false
interval: 20
out_put_path: /srv/bililive
feature:
use_native_flv_parser: false
live_rooms:
4 changes: 3 additions & 1 deletion config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ rpc:
key_file: ""
debug: false
interval: 15
out_put_path: ./
out_put_path: /Users/chigusa/Movies
feature:
use_native_flv_parser: false
live_rooms:
4 changes: 4 additions & 0 deletions src/configs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,15 @@ type RPC struct {
Token string `yaml:"token"`
TLS TLS `yaml:"tls"`
}
type Feature struct {
UseNativeFlvParser bool `yaml:"use_native_flv_parser"`
}
type Config struct {
RPC RPC `yaml:"rpc"`
Debug bool `yaml:"debug"`
Interval int `yaml:"interval"`
OutPutPath string `yaml:"out_put_path"`
Feature Feature `yaml:"feature"`
LiveRooms []string `yaml:"live_rooms"`
file string
}
Expand Down
43 changes: 43 additions & 0 deletions src/lib/parser/ffmpeg/ffmpeg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package ffmpeg

import (
"io"
"net/url"
"os/exec"
)

const (
userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36"
)

type Parser struct {
cmd *exec.Cmd
cmdStdIn io.WriteCloser
}

func New() *Parser {
return new(Parser)
}

func (p *Parser) ParseLiveStream(url *url.URL, file string) error {
p.cmd = exec.Command(
"ffmpeg",
"-loglevel", "warning",
"-y", "-re",
"-user_agent", userAgent,
"-timeout", "60000000",
"-i", url.String(),
"-c", "copy",
"-bsf:a", "aac_adtstoasc",
"-f", "flv",
file,
)
p.cmdStdIn, _ = p.cmd.StdinPipe()
p.cmd.Start()
return p.cmd.Wait()
}

func (p *Parser) Stop() error {
_, err := p.cmdStdIn.Write([]byte("q"))
return err
}
137 changes: 137 additions & 0 deletions src/lib/parser/native/flv/flv.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package flv

import (
"bytes"
"encoding/binary"
"errors"
"github.com/hr3lxphr6j/bililive-go/src/lib/reader"
"io"
"net/http"
"net/url"
"os"
)

const (
audioTag uint8 = 8
videoTag uint8 = 9
scriptTag uint8 = 18
)

var (
flvSign = []byte{0x46, 0x4c, 0x56, 0x01} // flv version01
NotFlvStream = errors.New("not flv stream")
UnknownTag = errors.New("unknown tag")
)

type Metadata struct {
HasVideo, HasAudio bool
}

type Parser struct {
Metadata Metadata

i *reader.BufferedReader
o io.Writer
avcHeaderCount uint8
tagCount uint32

hc *http.Client
stopCh chan struct{}
}

func NewParser() *Parser {
return &Parser{
Metadata: Metadata{},
hc: &http.Client{},
stopCh: make(chan struct{}),
}
}

func (p *Parser) ParseLiveStream(url *url.URL, file string) error {
// init input
req, err := http.NewRequest("GET", url.String(), nil)
req.Header.Add("User-Agent", "Chrome/59.0.3071.115")
if err != nil {
return err
}
resp, err := p.hc.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
p.i = reader.New(resp.Body)
defer p.i.Free()

// init output
f, err := os.OpenFile(file, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
return err
}
p.o = f
defer f.Close()

// start parse
return p.doParse()
}

func (p *Parser) Stop() error {
close(p.stopCh)
return nil
}

func (p *Parser) doParse() error {
// header of flv
b, err := p.i.ReadN(9)
if err != nil {
return err
}
// signature
if !bytes.Equal(b[:4], flvSign) {
return NotFlvStream
}
// flag
p.Metadata.HasVideo = uint8(b[4])&(1<<2) != 0
p.Metadata.HasAudio = uint8(b[4])&1 != 0

// offset must be 9
if binary.BigEndian.Uint32(b[5:]) != 9 {
return NotFlvStream
}

// write flv header
if err := p.doWrite(p.i.AllBytes()); err != nil {
return err
}
p.i.Reset()

for {
select {
case <-p.stopCh:
return nil
default:
if err := p.parseTag(); err != nil {
return err
}
}
}
}

func (p *Parser) doCopy(n uint32) error {
if n, err := io.CopyN(p.o, p.i, int64(n)); err != nil || n != int64(n) {
if err == nil {
err = io.EOF
}
return err
}
return nil
}

func (p *Parser) doWrite(b []byte) error {
if n, err := p.o.Write(b); err != nil || n != len(b) {
if err == nil {
err = io.EOF
}
return err
}
return nil
}
31 changes: 31 additions & 0 deletions src/lib/parser/native/flv/tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package flv

func (p *Parser) parseTag() error {
p.tagCount += 1

b, err := p.i.ReadN(15)
if err != nil {
return err
}

tagType := uint8(b[4])
length := uint32(b[5])<<16 | uint32(b[6])<<8 | uint32(b[7])
timeStamp := uint32(b[8])<<16 | uint32(b[9])<<8 | uint32(b[10]) | uint32(b[11])<<24

switch tagType {
case audioTag:
if _, err := p.parseAudioTag(length, timeStamp); err != nil {
return err
}
case videoTag:
if _, err := p.parseVideoTag(length, timeStamp); err != nil {
return err
}
case scriptTag:
return p.parseScriptTag(length)
default:
return UnknownTag
}

return nil
}
78 changes: 78 additions & 0 deletions src/lib/parser/native/flv/tag_audio.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package flv

type SoundFormat uint8
type SoundRate uint8
type SoundSize uint8
type SoundType uint8
type AACPacketType uint8
type AudioTagHeader struct {
SoundFormat SoundFormat
SoundRate SoundRate
SoundSize SoundSize
SoundType SoundType
AACPacketType AACPacketType
}

const (
// SoundFormat
LPCM_PE SoundFormat = 0 // Linear PCM, platform endian
ADPCM SoundFormat = 1
MP3 SoundFormat = 2
LPCM_LE SoundFormat = 3 // Linear PCM, little endian
AAC SoundFormat = 10
Speex SoundFormat = 11
MP3_8kHz SoundFormat = 14 // MP3 8 kHz

// SoundRate
Rate5kHz SoundRate = 0 // 5.5kHz
Rate11kHz SoundRate = 1 // 11 kHz
Rate22kHz SoundRate = 2 // 22 kHz
Rate44kHz SoundRate = 3 // 44 kHz

// SoundSize
Sample8 uint8 = 0 // 8-bit samples
Sample16 uint8 = 1 // 16-bit samples

// SoundType
Mono SoundType = 0 // Mono sound
Stereo SoundType = 1 // Stereo sound

// AACPacketType
AACSeqHeader AACPacketType = 0
AACRaw AACPacketType = 1
)

func (p *Parser) parseAudioTag(length, timestamp uint32) (*AudioTagHeader, error) {
b, err := p.i.ReadByte()
l := length - 1
if err != nil {
return nil, err
}
tag := new(AudioTagHeader)

tag.SoundFormat = SoundFormat(b >> 4 & 15)
tag.SoundRate = SoundRate(b >> 2 & 3)
tag.SoundSize = SoundSize(b >> 1 & 1)
tag.SoundType = SoundType(b & 1)

if tag.SoundFormat == AAC {
b, err := p.i.ReadByte()
l -= 1
if err != nil {
return nil, err
}
tag.AACPacketType = AACPacketType(b)
}

// write tag header && audio tag header & AACPacketType
if err := p.doWrite(p.i.AllBytes()); err != nil {
return nil, err
}
p.i.Reset()
// write body
if err := p.doCopy(l); err != nil {
return nil, err
}

return tag, nil
}
Loading

0 comments on commit d5e5057

Please sign in to comment.