mirror of
https://github.com/lkmio/lkm.git
synced 2025-10-05 15:16:49 +08:00
refactor: 拆分avformat依赖库
This commit is contained in:
@@ -1,10 +1,7 @@
|
||||
package stream
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/lkmio/avformat/libavc"
|
||||
"github.com/lkmio/avformat/libhevc"
|
||||
"github.com/lkmio/avformat/utils"
|
||||
"github.com/lkmio/lkm/log"
|
||||
"net/url"
|
||||
@@ -94,7 +91,7 @@ func (s SessionState) String() string {
|
||||
panic(fmt.Sprintf("unknown session state %d", s))
|
||||
}
|
||||
|
||||
func Path2SourceId(path string, suffix string) (string, error) {
|
||||
func Path2SourceID(path string, suffix string) (string, error) {
|
||||
source := strings.TrimSpace(path)
|
||||
if strings.HasPrefix(source, "/") {
|
||||
source = source[1:]
|
||||
@@ -129,95 +126,96 @@ func ParseUrl(name string) (string, url.Values) {
|
||||
return name, nil
|
||||
}
|
||||
|
||||
func ExtractVideoPacket(codec utils.AVCodecID, key, extractStream bool, data []byte, pts, dts int64, index, timebase int) (utils.AVStream, utils.AVPacket, error) {
|
||||
var stream utils.AVStream
|
||||
|
||||
if utils.AVCodecIdH264 == codec {
|
||||
//从关键帧中解析出sps和pps
|
||||
if key && extractStream {
|
||||
sps, pps, err := libavc.ParseExtraDataFromKeyNALU(data)
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("从关键帧中解析sps pps失败 data:%s", hex.EncodeToString(data))
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
codecData, err := utils.NewAVCCodecData(sps, pps)
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("解析sps pps失败 data:%s sps:%s, pps:%s", hex.EncodeToString(data), hex.EncodeToString(sps), hex.EncodeToString(pps))
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
stream = utils.NewAVStream(utils.AVMediaTypeVideo, 0, codec, codecData.AnnexBExtraData(), codecData)
|
||||
}
|
||||
|
||||
} else if utils.AVCodecIdH265 == codec {
|
||||
if key && extractStream {
|
||||
vps, sps, pps, err := libhevc.ParseExtraDataFromKeyNALU(data)
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("从关键帧中解析vps sps pps失败 data:%s", hex.EncodeToString(data))
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
codecData, err := utils.NewHEVCCodecData(vps, sps, pps)
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("解析sps pps失败 data:%s vps:%s sps:%s, pps:%s", hex.EncodeToString(data), hex.EncodeToString(vps), hex.EncodeToString(sps), hex.EncodeToString(pps))
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
stream = utils.NewAVStream(utils.AVMediaTypeVideo, 0, codec, codecData.AnnexBExtraData(), codecData)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
packet := utils.NewVideoPacket(data, dts, pts, key, utils.PacketTypeAnnexB, codec, index, timebase)
|
||||
return stream, packet, nil
|
||||
}
|
||||
|
||||
func ExtractAudioPacket(codec utils.AVCodecID, extractStream bool, data []byte, pts, dts int64, index, timebase int) (utils.AVStream, utils.AVPacket, error) {
|
||||
var stream utils.AVStream
|
||||
var packet utils.AVPacket
|
||||
if utils.AVCodecIdAAC == codec {
|
||||
//必须包含ADTSHeader
|
||||
if len(data) < 7 {
|
||||
return nil, nil, fmt.Errorf("need more data")
|
||||
}
|
||||
|
||||
var skip int
|
||||
header, err := utils.ReadADtsFixedHeader(data)
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("读取ADTSHeader失败 data:%s", hex.EncodeToString(data[:7]))
|
||||
return nil, nil, err
|
||||
} else {
|
||||
skip = 7
|
||||
//跳过ADtsHeader长度
|
||||
if header.ProtectionAbsent() == 0 {
|
||||
skip += 2
|
||||
}
|
||||
}
|
||||
|
||||
if extractStream {
|
||||
configData, err := utils.ADtsHeader2MpegAudioConfigData(header)
|
||||
config, err := utils.ParseMpeg4AudioConfig(configData)
|
||||
println(config)
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("adt头转m4ac失败 data:%s", hex.EncodeToString(data[:7]))
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
stream = utils.NewAVStream(utils.AVMediaTypeAudio, index, codec, configData, nil)
|
||||
}
|
||||
|
||||
packet = utils.NewAudioPacket(data[skip:], dts, pts, codec, index, timebase)
|
||||
} else if utils.AVCodecIdPCMALAW == codec || utils.AVCodecIdPCMMULAW == codec {
|
||||
if extractStream {
|
||||
stream = utils.NewAVStream(utils.AVMediaTypeAudio, index, codec, nil, nil)
|
||||
}
|
||||
|
||||
packet = utils.NewAudioPacket(data, dts, pts, codec, index, timebase)
|
||||
}
|
||||
|
||||
return stream, packet, nil
|
||||
}
|
||||
//
|
||||
//func ExtractVideoPacket(codec utils.AVCodecID, key, extractStream bool, data []byte, pts, dts int64, index, timebase int) (*avformat.AVStream, *avformat.AVPacket, error) {
|
||||
// var stream *avformat.AVStream
|
||||
//
|
||||
// if utils.AVCodecIdH264 == codec {
|
||||
// //从关键帧中解析出sps和pps
|
||||
// if key && extractStream {
|
||||
// sps, pps, err := avc.ParseExtraDataFromKeyNALU(data)
|
||||
// if err != nil {
|
||||
// log.Sugar.Errorf("从关键帧中解析sps pps失败 data:%s", hex.EncodeToString(data))
|
||||
// return nil, nil, err
|
||||
// }
|
||||
//
|
||||
// codecData, err := utils.NewAVCCodecData(sps, pps)
|
||||
// if err != nil {
|
||||
// log.Sugar.Errorf("解析sps pps失败 data:%s sps:%s, pps:%s", hex.EncodeToString(data), hex.EncodeToString(sps), hex.EncodeToString(pps))
|
||||
// return nil, nil, err
|
||||
// }
|
||||
//
|
||||
// stream = avformat.NewAVStream(utils.AVMediaTypeVideo, 0, codec, codecData.AnnexBExtraData(), codecData)
|
||||
// }
|
||||
//
|
||||
// } else if utils.AVCodecIdH265 == codec {
|
||||
// if key && extractStream {
|
||||
// vps, sps, pps, err := hevc.ParseExtraDataFromKeyNALU(data)
|
||||
// if err != nil {
|
||||
// log.Sugar.Errorf("从关键帧中解析vps sps pps失败 data:%s", hex.EncodeToString(data))
|
||||
// return nil, nil, err
|
||||
// }
|
||||
//
|
||||
// codecData, err := utils.NewHEVCCodecData(vps, sps, pps)
|
||||
// if err != nil {
|
||||
// log.Sugar.Errorf("解析sps pps失败 data:%s vps:%s sps:%s, pps:%s", hex.EncodeToString(data), hex.EncodeToString(vps), hex.EncodeToString(sps), hex.EncodeToString(pps))
|
||||
// return nil, nil, err
|
||||
// }
|
||||
//
|
||||
// stream = avformat.NewAVStream(utils.AVMediaTypeVideo, 0, codec, codecData.AnnexBExtraData(), codecData)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// packet := avformat.NewVideoPacket(data, dts, pts, key, utils.PacketTypeAnnexB, codec, index, timebase)
|
||||
// return stream, packet, nil
|
||||
//}
|
||||
//
|
||||
//func ExtractAudioPacket(codec utils.AVCodecID, extractStream bool, data []byte, pts, dts int64, index, timebase int) (*avformat.AVStream, *avformat.AVPacket, error) {
|
||||
// var stream *avformat.AVStream
|
||||
// var packet *avformat.AVPacket
|
||||
// if utils.AVCodecIdAAC == codec {
|
||||
// //必须包含ADTSHeader
|
||||
// if len(data) < 7 {
|
||||
// return nil, nil, fmt.Errorf("need more data")
|
||||
// }
|
||||
//
|
||||
// var skip int
|
||||
// header, err := utils.ReadADtsFixedHeader(data)
|
||||
// if err != nil {
|
||||
// log.Sugar.Errorf("读取ADTSHeader失败 data:%s", hex.EncodeToString(data[:7]))
|
||||
// return nil, nil, err
|
||||
// } else {
|
||||
// skip = 7
|
||||
// //跳过ADtsHeader长度
|
||||
// if header.ProtectionAbsent() == 0 {
|
||||
// skip += 2
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if extractStream {
|
||||
// configData, err := utils.ADtsHeader2MpegAudioConfigData(header)
|
||||
// config, err := utils.ParseMpeg4AudioConfig(configData)
|
||||
// println(config)
|
||||
// if err != nil {
|
||||
// log.Sugar.Errorf("adt头转m4ac失败 data:%s", hex.EncodeToString(data[:7]))
|
||||
// return nil, nil, err
|
||||
// }
|
||||
//
|
||||
// stream = avformat.NewAVStream(utils.AVMediaTypeAudio, index, codec, configData, nil)
|
||||
// }
|
||||
//
|
||||
// packet = utils.NewAudioPacket(data[skip:], dts, pts, codec, index, timebase)
|
||||
// } else if utils.AVCodecIdPCMALAW == codec || utils.AVCodecIdPCMMULAW == codec {
|
||||
// if extractStream {
|
||||
// stream = avformat.NewAVStream(utils.AVMediaTypeAudio, index, codec, nil, nil)
|
||||
// }
|
||||
//
|
||||
// packet = utils.NewAudioPacket(data, dts, pts, codec, index, timebase)
|
||||
// }
|
||||
//
|
||||
// return stream, packet, nil
|
||||
//}
|
||||
|
||||
// StartReceiveDataTimer 启动收流超时计时器
|
||||
func StartReceiveDataTimer(source Source) *time.Timer {
|
||||
@@ -308,7 +306,7 @@ func LoopEvent(source Source) {
|
||||
}
|
||||
|
||||
if err := source.Input(data); err != nil {
|
||||
log.Sugar.Errorf("处理输入流失败 释放source:%s err:%s", source.GetID(), err.Error())
|
||||
log.Sugar.Errorf("解析推流数据发生err: %s 释放source: %s", err.Error(), source.GetID())
|
||||
source.DoClose()
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user