Skip to content

Commit

Permalink
made useable by ffmpeg 4.1
Browse files Browse the repository at this point in the history
  • Loading branch information
laice committed Feb 26, 2019
1 parent 40b45c9 commit 8391408
Show file tree
Hide file tree
Showing 50 changed files with 912 additions and 877 deletions.
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ JOY4 is powerful library written in golang, well-designed interface makes a few

Well-designed and easy-to-use interfaces:

- Muxer / Demuxer ([doc](https://godoc.org/github.com/nareix/joy4/av#Demuxer) [example](https://github.com/nareix/joy4/blob/master/examples/open_probe_file/main.go))
- Audio Decoder ([doc](https://godoc.org/github.com/nareix/joy4/av#AudioDecoder) [example](https://github.com/nareix/joy4/blob/master/examples/audio_decode/main.go))
- Transcoding ([doc](https://godoc.org/github.com/nareix/joy4/av/transcode) [example](https://github.com/nareix/joy4/blob/master/examples/transcode/main.go))
- Streaming server ([example](https://github.com/nareix/joy4/blob/master/examples/http_flv_and_rtmp_server/main.go))
- Muxer / Demuxer ([doc](https://godoc.org/github.com/laice/joy4/av#Demuxer) [example](https://github.com/laice/joy4/blob/master/examples/open_probe_file/main.go))
- Audio Decoder ([doc](https://godoc.org/github.com/laice/joy4/av#AudioDecoder) [example](https://github.com/laice/joy4/blob/master/examples/audio_decode/main.go))
- Transcoding ([doc](https://godoc.org/github.com/laice/joy4/av/transcode) [example](https://github.com/laice/joy4/blob/master/examples/transcode/main.go))
- Streaming server ([example](https://github.com/laice/joy4/blob/master/examples/http_flv_and_rtmp_server/main.go))

Support container formats:

Expand All @@ -34,31 +34,31 @@ RTMP / HTTP-FLV Server
- High performance


Publisher-subscriber packet buffer queue ([doc](https://godoc.org/github.com/nareix/joy4/av/pubsub))
Publisher-subscriber packet buffer queue ([doc](https://godoc.org/github.com/laice/joy4/av/pubsub))

- Customize publisher buffer time and subscriber read position


- Multiple channels live streaming ([example](https://github.com/nareix/joy4/blob/master/examples/rtmp_server_channels/main.go))
- Multiple channels live streaming ([example](https://github.com/laice/joy4/blob/master/examples/rtmp_server_channels/main.go))

Packet filters ([doc](https://godoc.org/github.com/nareix/joy4/av/pktque))
Packet filters ([doc](https://godoc.org/github.com/laice/joy4/av/pktque))

- Wait first keyframe
- Fix timestamp
- Make A/V sync
- Customize ([example](https://github.com/nareix/joy4/blob/master/examples/rtmp_server_channels/main.go#L19))
- Customize ([example](https://github.com/laice/joy4/blob/master/examples/rtmp_server_channels/main.go#L19))

FFMPEG Golang-style binding ([doc](https://godoc.org/github.com/nareix/joy4/cgo/ffmpeg))
FFMPEG Golang-style binding ([doc](https://godoc.org/github.com/laice/joy4/cgo/ffmpeg))
- Audio Encoder / Decoder
- Video Decoder
- Audio Resampler

Support codec and container parsers:

- H264 SPS/PPS/AVCDecoderConfigure parser ([doc](https://godoc.org/github.com/nareix/joy4/codec/h264parser))
- AAC ADTSHeader/MPEG4AudioConfig parser ([doc](https://godoc.org/github.com/nareix/joy4/codec/aacparser))
- MP4 Atoms parser ([doc](https://godoc.org/github.com/nareix/joy4/format/mp4/mp4io))
- FLV AMF0 object parser ([doc](https://godoc.org/github.com/nareix/joy4/format/flv/flvio))
- H264 SPS/PPS/AVCDecoderConfigure parser ([doc](https://godoc.org/github.com/laice/joy4/codec/h264parser))
- AAC ADTSHeader/MPEG4AudioConfig parser ([doc](https://godoc.org/github.com/laice/joy4/codec/aacparser))
- MP4 Atoms parser ([doc](https://godoc.org/github.com/laice/joy4/format/mp4/mp4io))
- FLV AMF0 object parser ([doc](https://godoc.org/github.com/laice/joy4/format/flv/flvio))

# Requirements

Expand Down
90 changes: 44 additions & 46 deletions av/av.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

// Package av defines basic interfaces and data structures of container demux/mux and audio encode/decode.
package av

Expand All @@ -11,17 +10,17 @@ import (
type SampleFormat uint8

const (
U8 = SampleFormat(iota + 1) // 8-bit unsigned integer
S16 // signed 16-bit integer
S32 // signed 32-bit integer
FLT // 32-bit float
DBL // 64-bit float
U8P // 8-bit unsigned integer in planar
S16P // signed 16-bit integer in planar
S32P // signed 32-bit integer in planar
FLTP // 32-bit float in planar
DBLP // 64-bit float in planar
U32 // unsigned 32-bit integer
U8 = SampleFormat(iota + 1) // 8-bit unsigned integer
S16 // signed 16-bit integer
S32 // signed 32-bit integer
FLT // 32-bit float
DBL // 64-bit float
U8P // 8-bit unsigned integer in planar
S16P // signed 16-bit integer in planar
S32P // signed 32-bit integer in planar
FLTP // 32-bit float in planar
DBLP // 64-bit float in planar
U32 // unsigned 32-bit integer
)

func (self SampleFormat) BytesPerSample() int {
Expand Down Expand Up @@ -116,11 +115,11 @@ func (self ChannelLayout) Count() (n int) {
type CodecType uint32

var (
H264 = MakeVideoCodecType(avCodecTypeMagic + 1)
AAC = MakeAudioCodecType(avCodecTypeMagic + 1)
PCM_MULAW = MakeAudioCodecType(avCodecTypeMagic + 2)
PCM_ALAW = MakeAudioCodecType(avCodecTypeMagic + 3)
SPEEX = MakeAudioCodecType(avCodecTypeMagic + 4)
H264 = MakeVideoCodecType(avCodecTypeMagic + 1)
AAC = MakeAudioCodecType(avCodecTypeMagic + 1)
PCM_MULAW = MakeAudioCodecType(avCodecTypeMagic + 2)
PCM_ALAW = MakeAudioCodecType(avCodecTypeMagic + 3)
SPEEX = MakeAudioCodecType(avCodecTypeMagic + 4)
NELLYMOSER = MakeAudioCodecType(avCodecTypeMagic + 5)
)

Expand Down Expand Up @@ -171,23 +170,23 @@ const avCodecTypeMagic = 233333
// can be converted to VideoCodecData or AudioCodecData using:
//
// codecdata.(AudioCodecData) or codecdata.(VideoCodecData)
//
//
// for H264, CodecData is AVCDecoderConfigure bytes, includes SPS/PPS.
type CodecData interface {
Type() CodecType // Video/Audio codec type
}

type VideoCodecData interface {
CodecData
Width() int // Video height
Width() int // Video height
Height() int // Video width
}

type AudioCodecData interface {
CodecData
SampleFormat() SampleFormat // audio sample format
SampleRate() int // audio sample rate
ChannelLayout() ChannelLayout // audio channel layout
SampleFormat() SampleFormat // audio sample format
SampleRate() int // audio sample rate
ChannelLayout() ChannelLayout // audio channel layout
PacketDuration([]byte) (time.Duration, error) // get audio compressed packet duration
}

Expand All @@ -196,16 +195,16 @@ type PacketWriter interface {
}

type PacketReader interface {
ReadPacket() (Packet,error)
ReadPacket() (Packet, error)
}

// Muxer describes the steps of writing compressed audio/video packets into container formats like MP4/FLV/MPEG-TS.
//
//
// Container formats, rtmp.Conn, and transcode.Muxer implements Muxer interface.
type Muxer interface {
WriteHeader([]CodecData) error // write the file header
PacketWriter // write compressed audio/video packets
WriteTrailer() error // finish writing file, this func can be called only once
PacketWriter // write compressed audio/video packets
WriteTrailer() error // finish writing file, this func can be called only once
}

// Muxer with Close() method
Expand All @@ -216,7 +215,7 @@ type MuxCloser interface {

// Demuxer can read compressed audio/video packets from container formats like MP4/FLV/MPEG-TS.
type Demuxer interface {
PacketReader // read compressed audio/video packets
PacketReader // read compressed audio/video packets
Streams() ([]CodecData, error) // reads the file header, contains video/audio meta infomations
}

Expand All @@ -228,20 +227,20 @@ type DemuxCloser interface {

// Packet stores compressed audio/video data.
type Packet struct {
IsKeyFrame bool // video packet is key frame
Idx int8 // stream index in container format
IsKeyFrame bool // video packet is key frame
Idx int8 // stream index in container format
CompositionTime time.Duration // packet presentation time minus decode time for H264 B-Frame
Time time.Duration // packet decode time
Data []byte // packet data
Time time.Duration // packet decode time
Data []byte // packet data
}

// Raw audio frame.
type AudioFrame struct {
SampleFormat SampleFormat // audio sample format, e.g: S16,FLTP,...
SampleFormat SampleFormat // audio sample format, e.g: S16,FLTP,...
ChannelLayout ChannelLayout // audio channel layout, e.g: CH_MONO,CH_STEREO,...
SampleCount int // sample count in this frame
SampleRate int // sample rate
Data [][]byte // data array for planar format len(Data) > 1
SampleCount int // sample count in this frame
SampleRate int // sample rate
Data [][]byte // data array for planar format len(Data) > 1
}

func (self AudioFrame) Duration() time.Duration {
Expand Down Expand Up @@ -291,26 +290,25 @@ func (self AudioFrame) Concat(in AudioFrame) (out AudioFrame) {
// AudioEncoder can encode raw audio frame into compressed audio packets.
// cgo/ffmpeg inplements AudioEncoder, using ffmpeg.NewAudioEncoder to create it.
type AudioEncoder interface {
CodecData() (AudioCodecData, error) // encoder's codec data can put into container
Encode(AudioFrame) ([][]byte, error) // encode raw audio frame into compressed pakcet(s)
Close() // close encoder, free cgo contexts
SetSampleRate(int) (error) // set encoder sample rate
SetChannelLayout(ChannelLayout) (error) // set encoder channel layout
SetSampleFormat(SampleFormat) (error) // set encoder sample format
SetBitrate(int) (error) // set encoder bitrate
SetOption(string,interface{}) (error) // encoder setopt, in ffmpeg is av_opt_set_dict()
GetOption(string,interface{}) (error) // encoder getopt
CodecData() (AudioCodecData, error) // encoder's codec data can put into container
Encode(AudioFrame) ([][]byte, error) // encode raw audio frame into compressed pakcet(s)
Close() // close encoder, free cgo contexts
SetSampleRate(int) error // set encoder sample rate
SetChannelLayout(ChannelLayout) error // set encoder channel layout
SetSampleFormat(SampleFormat) error // set encoder sample format
SetBitrate(int) error // set encoder bitrate
SetOption(string, interface{}) error // encoder setopt, in ffmpeg is av_opt_set_dict()
GetOption(string, interface{}) error // encoder getopt
}

// AudioDecoder can decode compressed audio packets into raw audio frame.
// use ffmpeg.NewAudioDecoder to create it.
type AudioDecoder interface {
Decode([]byte) (bool, AudioFrame, error) // decode one compressed audio packet
Close() // close decode, free cgo contexts
Close() // close decode, free cgo contexts
}

// AudioResampler can convert raw audio frames in different sample rate/format/channel layout.
type AudioResampler interface {
Resample(AudioFrame) (AudioFrame, error) // convert raw audio frames
}

27 changes: 13 additions & 14 deletions av/avconv/avconv.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ package avconv

import (
"fmt"
"github.com/laice/joy4/av"
"github.com/laice/joy4/av/avutil"
"github.com/laice/joy4/av/pktque"
"github.com/laice/joy4/av/transcode"
"io"
"time"
"github.com/nareix/joy4/av/avutil"
"github.com/nareix/joy4/av"
"github.com/nareix/joy4/av/pktque"
"github.com/nareix/joy4/av/transcode"
)

var Debug bool

type Option struct {
Transcode bool
Args []string
Args []string
}

type Options struct {
Expand All @@ -23,7 +23,7 @@ type Options struct {

type Demuxer struct {
transdemux *transcode.Demuxer
streams []av.CodecData
streams []av.CodecData
Options
Demuxer av.Demuxer
}
Expand Down Expand Up @@ -56,10 +56,10 @@ func (self *Demuxer) prepare() (err error) {
}

/*
var streams []av.CodecData
if streams, err = self.Demuxer.Streams(); err != nil {
return
}
var streams []av.CodecData
if streams, err = self.Demuxer.Streams(); err != nil {
return
}
*/

supports := self.Options.OutputCodecTypes
Expand All @@ -83,7 +83,7 @@ func (self *Demuxer) prepare() (err error) {
ok = true

var enctype av.CodecType
for _, typ:= range supports {
for _, typ := range supports {
if typ.IsAudio() {
if enc, _ = avutil.DefaultHandlers.NewAudioEncoder(typ); enc != nil {
enctype = typ
Expand Down Expand Up @@ -152,7 +152,7 @@ func ConvertCmdline(args []string) (err error) {
flagt = false
var f float64
fmt.Sscanf(arg, "%f", &f)
duration = time.Duration(f*float64(time.Second))
duration = time.Duration(f * float64(time.Second))

default:
output = arg
Expand Down Expand Up @@ -223,7 +223,7 @@ func ConvertCmdline(args []string) (err error) {
}
filterdemux := &pktque.FilterDemuxer{
Demuxer: convdemux,
Filter: filters,
Filter: filters,
}

for {
Expand Down Expand Up @@ -252,4 +252,3 @@ func ConvertCmdline(args []string) (err error) {

return
}

Loading

0 comments on commit 8391408

Please sign in to comment.