diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8864d4a --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/decoder.go b/decoder.go index 2502503..a54c8cd 100644 --- a/decoder.go +++ b/decoder.go @@ -18,6 +18,12 @@ type decoder struct { codecType int } +func decodeAVPacket(packet *C.AVPacket) (data []byte) { + data = make([]byte, int(packet.size)) + copy(data, *(*[]byte)(unsafe.Pointer(&packet.data))) + return +} + func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { pkt = &Packet{} @@ -47,10 +53,14 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { return } + pkt.duration = int64(frame.pkt_duration) + pkt.position = int64(frame.pkt_pos) + switch decoder.codecType { case C.AVMEDIA_TYPE_VIDEO: pkt.width = int(frame.width) pkt.height = int(frame.height) + pkt.keyFrame = int(frame.key_frame) == 1 var encPacket C.AVPacket defer C.av_packet_unref(&encPacket) @@ -69,8 +79,7 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { } } - pkt.data = make([]byte, int(encPacket.size)) - copy(pkt.data, *(*[]byte)(unsafe.Pointer(&encPacket.data))) + pkt.data = decodeAVPacket(&encPacket) case C.AVMEDIA_TYPE_AUDIO: pkt.bitRate = int(decoder.codecCtx.bit_rate) @@ -108,8 +117,7 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { err = fmt.Errorf("ffmpeg: rtsp_avcodec_encode_resample_wav failed: %d", cerr) return } - pkt.data = make([]byte, int(encPacket.size)) - copy(pkt.data, *(*[]byte)(unsafe.Pointer(&encPacket.data))) + pkt.data = decodeAVPacket(&encPacket) case C.AV_SAMPLE_FMT_S16: var encPacket C.AVPacket @@ -119,9 +127,7 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { err = fmt.Errorf("ffmpeg: rtsp_avcodec_encode_wav failed: %d", cerr) return } - - pkt.data = make([]byte, int(encPacket.size)) - copy(pkt.data, *(*[]byte)(unsafe.Pointer(&encPacket.data))) + pkt.data = decodeAVPacket(&encPacket) case C.AV_SAMPLE_FMT_S32: if decoder.swrContext == nil { @@ -153,8 +159,8 @@ func (decoder *decoder) Decode(packet *C.AVPacket) (pkt *Packet, err error) { err = fmt.Errorf("ffmpeg: rtsp_avcodec_encode_resample_wav failed: %d", cerr) return } - pkt.data = make([]byte, int(encPacket.size)) - copy(pkt.data, *(*[]byte)(unsafe.Pointer(&encPacket.data))) + pkt.data = decodeAVPacket(&encPacket) + default: err = fmt.Errorf("ffmpeg: audio format %d not supported: %d", frame.format) return diff --git a/doc.go b/doc.go new file mode 100644 index 0000000..d608818 --- /dev/null +++ b/doc.go @@ -0,0 +1,3 @@ +// Package go-rtsp is a Golang audio/video library based on FFmpeg. +// go-rtsp is powerful library to help convert streams/files to jpeg/wav. +package rtsp diff --git a/pkt.go b/pkt.go index c255614..dc9b775 100644 --- a/pkt.go +++ b/pkt.go @@ -3,57 +3,68 @@ package rtsp // #include "ffmpeg.h" import "C" -type Packet struct { - streamIndex int - codecType int - data []byte - +type Image struct { // only image - width int - height int + width int + height int + keyFrame bool +} +// Height if image or 0 if audio +func (image *Image) Height() int { + return image.height +} + +// Width if image or 0 if audio +func (image *Image) Width() int { + return image.width +} + +type Audio struct { // only audio sampleRate int bitRate int channels int } -// Height if image or 0 if audio -func (pkt *Packet) Height() int { - return pkt.height -} - -// Width if image or 0 if audio -func (pkt *Packet) Width() int { - return pkt.width -} - // SampleRate if audio or 0 if image -func (pkt *Packet) SampleRate() int { - return pkt.sampleRate +func (audio *Audio) SampleRate() int { + return audio.sampleRate } // BitRate if audio or 0 if image -func (pkt *Packet) BitRate() int { - return pkt.bitRate +func (audio *Audio) BitRate() int { + return audio.bitRate } -// BitRate if audio or 0 if image -func (pkt *Packet) Channels() int { - return pkt.channels +// Channels if audio or 0 if image +func (audio *Audio) Channels() int { + return audio.channels +} + +type Packet struct { + streamIndex int + codecType int + data []byte + + duration int64 + position int64 + + Image + Audio } // Data encoded jpeg if image or wav if audio -func (pkt *Packet) Data() []byte { - return pkt.data +func (packet *Packet) Data() []byte { + return packet.data } // IsAudio packet -func (pkt *Packet) IsAudio() bool { - return pkt.codecType == C.AVMEDIA_TYPE_AUDIO +func (packet *Packet) IsAudio() bool { + return packet.codecType == C.AVMEDIA_TYPE_AUDIO } // IsVideo packet -func (pkt *Packet) IsVideo() bool { - return pkt.codecType == C.AVMEDIA_TYPE_VIDEO +func (packet *Packet) IsVideo() bool { + return packet.codecType == C.AVMEDIA_TYPE_VIDEO }