参考代码:
LiveTalking/app.py at 16774890b8d76ece2a2293c9b71cd8265986f329 · lex2029/LiveTalking
python
def _enable_h264_nvenc() -> bool:
try:
import fractions
import av
import aiortc.codecs as codecs
import aiortc.codecs.h264 as h264
except Exception as exc:
logger.info("NVENC init skipped: %s", exc)
return False
try:
av.CodecContext.create("h264_nvenc", "w")
except av.AVError as exc:
logger.info("NVENC not available: %s", exc)
return False
class H264EncoderNVENC(h264.H264Encoder):
def _encode_frame(self, frame, force_keyframe: bool):
if self.codec and (
frame.width != self.codec.width
or frame.height != self.codec.height
or abs(self.target_bitrate - self.codec.bit_rate) / self.codec.bit_rate
> 0.1
):
self.buffer_data = b""
self.buffer_pts = None
self.codec = None
if force_keyframe:
frame.pict_type = av.video.frame.PictureType.I
else:
frame.pict_type = av.video.frame.PictureType.NONE
if self.codec is None:
try:
codec = av.CodecContext.create("h264_nvenc", "w")
except av.AVError:
codec = av.CodecContext.create("libx264", "w")
codec.width = frame.width
codec.height = frame.height
codec.bit_rate = self.target_bitrate
codec.pix_fmt = "yuv420p"
codec.framerate = fractions.Fraction(h264.MAX_FRAME_RATE, 1)
codec.time_base = fractions.Fraction(1, h264.MAX_FRAME_RATE)
if codec.name == "h264_nvenc":
try:
codec.options = {
"preset": "p3",
"rc": "cbr",
"bf": "0",
"g": "60",
"tune": "ll",
}
except Exception:
codec.options = {}
try:
codec.profile = "baseline"
except Exception:
pass
else:
codec.options = {
"level": "31",
"tune": "zerolatency",
}
codec.profile = "Baseline"
self.codec = codec
data_to_send = b""
for package in self.codec.encode(frame):
data_to_send += bytes(package)
if data_to_send:
yield from self._split_bitstream(data_to_send)
h264.H264Encoder = H264EncoderNVENC
codecs.H264Encoder = H264EncoderNVENC
logger.info("Using NVENC H264 encoder")
return True
_H264_NVENC_ENABLED = _enable_h264_nvenc()