七牛直播推流端flutter插件,支持Android和iOS
七牛直播推流端flutter插件,支持Android和iOS
·
// Android native 侧参数,用于推流相关参数配置,参数名称和七牛推流SDK基本一致
data class AVStreamingConfig(
/**
* 忽略HTTPS证书验证
*/
var disableCertificateValidation: Boolean = false,
var logLevel: Int? = null,
var isLogFileEnabled: Boolean = false,
var isTorchOn: Boolean = false,
var publishUrl: String? = null,
var uid: String? = null,
var isQuicEnabled: Boolean = false,
var isSrtEnabled: Boolean = false,
/**
* StreamingProfile
*/
var isAudioOnly: Boolean = false,
var videoQuality: Int = VIDEO_QUALITY_HIGH1,
var encodingSizeLevel: Int? = null,
var encodingOrientation: ENCODING_ORIENTATION = ENCODING_ORIENTATION.PORT,
var encoderRCMode: EncoderRCModes = EncoderRCModes.QUALITY_PRIORITY,
var isVideoFPSControl: Boolean = true,
var pictureStreamingAssetName: String? = null,
var audioQuality: Int = AUDIO_QUALITY_MEDIUM2,
var audioQualitySampleRate: Int? = null,
var audioQualityBitrate: Int? = null,
var videoQualityFPS: Int? = null,
var videoQualityBitrate: Int? = null,
var videoQualityMaxKeyFrameInterval: Int? = null,
var videoQualityProfile: H264Profile? = null,
var preferredVideoEncodingWidth: Int = 480,
var preferredVideoEncodingHeight: Int = 848,
var bitrateAdjustMode: BitrateAdjustMode = BitrateAdjustMode.Auto,
/**
* bitrateAdjustMode == BitrateAdjustMode.Auto 时生效
*/
var videoAdaptiveBitrateMin: Int = 800,
/**
* bitrateAdjustMode == BitrateAdjustMode.Auto 时生效
*/
var videoAdaptiveBitrateMax: Int = 1500,
var codecType: AVCodecType = AVCodecType.HW_VIDEO_CODEC,
var yuvFilterMode: YuvFilterMode = YuvFilterMode.Linear,
var tcpSendTimeAdjustThreshold: Int? = null,
var fpsAdjustThreshold: Int? = null,
var isFpsControllerEnable: Boolean? = null,
var latency: Int? = null,
var localFileAbsolutePath: String? = null,
var pictureStreamingFilePath: String? = null,
var pictureStreamingFps: Float? = null,
var pictureStreamingResourceName: String? = null,
var preferredVideoEncodingStartPointX: Int? = null,
var preferredVideoEncodingStartPointY: Int? = null,
var preferredVideoEncodingImgWidth: Int? = null,
var preferredVideoEncodingImgHeight: Int? = null,
//setRtmpOptions
var sendingBufferLowThreshold: Float? = null,
var sendingBufferHighThreshold: Float? = null,
var sendingBufferDurationLimit: Float? = null,
var sendingBufferLowThresholdTimeout: Long? = null,
var sendTimeoutInSecond: Int? = null,
var streamId: String? = null,
var streamHubName: String? = null,
var streamTitle: String? = null,
var streamPublishKey: String? = null,
var streamPublishSecurity: String? = null,
var streamPublishRtmpHost: String? = null,
/**
* [StreamStatusConfig]
*/
var streamIntervalMs: Int? = null,
/**
* 是否开启水印
*/
var watermarkAssetName: String? = null, // 水印图片名称(flutter端 yaml 文件中的名称)
var watermarkResourcePath: String? = null, // 水印图片名称(手机文件存储的文件路径)
var watermarkResourceName: String? = null, // 水印图片资源名称(Android端 R.drawable.<ResourceName> 中的<ResourceName>)
var watermarkLocation: WATERMARK_LOCATION = WATERMARK_LOCATION.NORTH_WEST, // WatermarkSetting.setLocation()
var watermarkLocationX: Float? = null, // WatermarkSetting.setCustomPosition()
var watermarkLocationY: Float? = null, // WatermarkSetting.setCustomPosition()
var watermarkAlpha: Int = 100, // WatermarkSetting.alpha
var watermarkSize: WATERMARK_SIZE = WATERMARK_SIZE.MEDIUM, // WatermarkSetting.setSize()
var watermarkWidth: Int? = null, // WatermarkSetting.setCustomSize()
var watermarkHeight: Int? = null, // WatermarkSetting.setCustomSize()
var watermarkIsInJustDecodeBoundsEnabled: Boolean? = null,
/**
* DNS配置
*/
var httpDnsServers: List<String>? = null,
var udpDnsServers: List<String>? = null,
/**
* Camera配置
*/
var frontFacing: Boolean = true, // 是否使用前置摄像头
var cameraPrvSizeLevel: PREVIEW_SIZE_LEVEL = PREVIEW_SIZE_LEVEL.MEDIUM, // CameraStreamingSetting.setCameraPrvSizeLevel()
var cameraPrvSizeRatio: PREVIEW_SIZE_RATIO = PREVIEW_SIZE_RATIO.RATIO_16_9, // CameraStreamingSetting.setCameraPrvSizeRatio()
var focusMode: String = FocusMode.CONTINUOUS_VIDEO.mode, // CameraStreamingSetting.focusMode
var videoFilter: VIDEO_FILTER_TYPE = VIDEO_FILTER_TYPE.VIDEO_FILTER_BEAUTY, // CameraStreamingSetting.setVideoFilter()
var isBuiltInFaceBeautyEnabled: Boolean = false, // CameraStreamingSetting.setBuiltInFaceBeautyEnabled
var faceBeautyLevel: Float = 0.6f, // CameraStreamingSetting.FaceBeautySetting
var faceBeautyWhiten: Float = 0.6f, // CameraStreamingSetting.FaceBeautySetting
var faceBeautyRedden: Float = 0.6f, // CameraStreamingSetting.FaceBeautySetting
var isContinuousFocusModeEnabled: Boolean = true, // CameraStreamingSetting.setContinuousFocusModeEnabled()
var isFrontCameraPreviewMirror: Boolean = false, // CameraStreamingSetting.isFrontCameraPreviewMirror
var isFrontCameraMirror: Boolean = false, // CameraStreamingSetting.isFrontCameraMirror
var isPreviewAdaptToEncodingSize: Boolean? = null,
var isPreviewSizeOptimize: Boolean? = null,
var isCaptureCameraFrameOnly: Boolean? = null,
var isRecordingHint: Boolean? = null,
var resetTouchFocusDelayInMs: Int? = null,
/**
* Microphone配置
*/
var isBluetoothScoEnabled: Boolean? = null,
var isAECEnabled: Boolean? = null, // MicrophoneStreamingSetting.setAECEnabled(boolean)
var isAudioPtsOptimizeEnabled: Boolean? = null, // MicrophoneStreamingSetting.setAudioPtsOptimizeEnabled(boolean)
var isCaptureAudioFrameOnly: Boolean? = null,
var sampleRate: Int? = null,
/**
* [MediaRecorder.AudioSource]
*/
var audioSource: Int? = null, // 设置 MediaRecorder.AudioSource.VOICE_COMMUNICATION
/**
* [AudioFormat]
*/
var channelConfig: Int? = null, // 立体声,不是所有手机都有效,设置 AudioFormat.CHANNEL_IN_STEREO
var isMuted: Boolean = false // 是否静音
) {}
import 'dart:core';
// flutter端的参数配置
class AndroidAVStreamingConfig {
/// 忽略HTTPS证书验证
bool? disableCertificateValidation;
/// 2: VERBOSE
/// 3: DEBUG
/// 4: INFO
/// 5: WARN
/// 6: ERROR
/// other: ERROR
int? logLevel;
bool? logFileEnabled;
String? publishUrl;
String? uid;
bool? isQuicEnabled;
bool? isSrtEnabled;
/// StreamingProfile
bool? isAudioOnly;
/// 0: VIDEO_QUALITY_LOW1
/// 1: VIDEO_QUALITY_LOW2
/// 2: VIDEO_QUALITY_LOW3
/// 3: VIDEO_QUALITY_MEDIUM1
/// 4: VIDEO_QUALITY_MEDIUM2
/// 5: VIDEO_QUALITY_MEDIUM3
/// 6: VIDEO_QUALITY_HIGH1
/// 7: VIDEO_QUALITY_HIGH2
/// 8: VIDEO_QUALITY_HIGH3
/// default 6
int? videoQuality;
int? encodingSizeLevel;
/// 0: PORT
/// 1: LAND
/// default 0
int? encodingOrientation;
/// 0: QUALITY_PRIORITY
/// 1: BITRATE_PRIORITY
/// default 0
int? encoderRCMode;
/// default true
bool? isVideoFPSControl;
String? pictureStreamingAssetName;
/// 0: AUDIO_QUALITY_LOW1
/// 1: AUDIO_QUALITY_LOW2
/// 2: AUDIO_QUALITY_MEDIUM1
/// 3: AUDIO_QUALITY_MEDIUM2
/// 4: AUDIO_QUALITY_HIGH1
/// 5: AUDIO_QUALITY_HIGH2
/// default 3
int? audioQuality;
int? audioQualitySampleRate;
int? audioQualityBitrate;
int? videoQualityFPS;
int? videoQualityBitrate;
int? videoQualityMaxKeyFrameInterval;
/// 0: BASELINE
/// 1: MAIN
/// 2: HIGH
/// default null
int? videoQualityProfile;
/// default 480
int? preferredVideoEncodingWidth;
/// default 848
int? preferredVideoEncodingHeight;
/// 0: Auto
/// 1: Manual
/// 2: Disable
/// default 0
int? bitrateAdjustMode;
/// bitrateAdjustMode == BitrateAdjustMode.Auto 时生效, default 800
int? videoAdaptiveBitrateMin;
/// bitrateAdjustMode == BitrateAdjustMode.Auto 时生效, default 1500
int? videoAdaptiveBitrateMax;
/// 0: HW_VIDEO_WITH_HW_AUDIO_CODEC
/// 1: SW_VIDEO_WITH_HW_AUDIO_CODEC
/// 2: SW_VIDEO_WITH_SW_AUDIO_CODEC
/// 3: SW_AUDIO_CODEC
/// 4: HW_AUDIO_CODEC
/// 5: SW_VIDEO_CODEC
/// 6: HW_VIDEO_CODEC
/// 7: HW_VIDEO_SURFACE_AS_INPUT_WITH_HW_AUDIO_CODEC
/// 8: HW_VIDEO_YUV_AS_INPUT_WITH_HW_AUDIO_CODEC
/// 9: HW_VIDEO_SURFACE_AS_INPUT_WITH_SW_AUDIO_CODEC
/// default 6
int? codecType;
/// 0: None
/// 1: Linear
/// 2: Bilinear
/// 3: Box
/// default 1
int? yuvFilterMode;
/// 水印图片名称(flutter端 yaml 文件中的名称)
String? watermarkAssetName;
/// 水印图片名称(手机文件存储的文件路径)
String? watermarkResourcePath;
/// 水印图片资源名称(Android端 R.drawable.<ResourceName> 中的<ResourceName>)
String? watermarkResourceName;
/// 0: NORTH_WEST
/// 1: NORTH_EAST
/// 2: SOUTH_WEST
/// 3: SOUTH_EAST
int? watermarkLocation;
/// default 0.5
double? watermarkLocationX;
/// default 0.5
double? watermarkLocationY;
/// default 100
int? watermarkAlpha;
/// 0: LARGE
/// 1: MEDIUM
/// 2: SMALL
/// default 1
int? watermarkSize;
int? watermarkWidth;
int? watermarkHeight;
bool? watermarkIsInJustDecodeBoundsEnabled;
int? tcpSendTimeAdjustThreshold;
int? fpsAdjustThreshold;
bool? isFpsControllerEnable;
int? latency;
String? localFileAbsolutePath;
String? pictureStreamingFilePath;
double? pictureStreamingFps;
String? pictureStreamingResourceName;
int? preferredVideoEncodingStartPointX;
int? preferredVideoEncodingStartPointY;
int? preferredVideoEncodingImgWidth;
int? preferredVideoEncodingImgHeight;
double? sendingBufferLowThreshold;
double? sendingBufferHighThreshold;
double? sendingBufferDurationLimit;
int? sendingBufferLowThresholdTimeout;
int? sendTimeoutInSecond;
String? streamId;
String? streamHubName;
String? streamTitle;
String? streamPublishKey;
String? streamPublishSecurity;
String? streamPublishRtmpHost;
int? streamIntervalMs;
/// DNS配置
List<String>? httpDnsServers;
List<String>? udpDnsServers;
/// Camera配置
/// 是否使用前置摄像头
bool? frontFacing;
/// 0: SMALL
/// 1: MEDIUM
/// 2: LARGE
/// default 1
int? cameraPrvSizeLevel;
/// 0: RATIO_4_3
/// 1: RATIO_16_9
/// default 1
int? cameraPrvSizeRatio;
/// 0: FOCUS_MODE_AUTO
/// 1: FOCUS_MODE_CONTINUOUS_PICTURE
/// 2: FOCUS_MODE_CONTINUOUS_VIDEO
/// default 1
int? focusMode;
/// 0: VIDEO_FILTER_NONE,
/// 1: VIDEO_FILTER_BEAUTY;
int? videoFilter;
bool? isBuiltInFaceBeautyEnabled;
/// default 0.6
double? faceBeautyLevel;
/// default 0.6
double? faceBeautyWhiten;
/// default 0.6
double? faceBeautyRedden;
/// default true
bool? isContinuousFocusModeEnabled;
bool? isFrontCameraPreviewMirror;
bool? isFrontCameraMirror;
bool? isPreviewAdaptToEncodingSize;
bool? isPreviewSizeOptimize;
bool? isCaptureCameraFrameOnly;
bool? isRecordingHint;
int? resetTouchFocusDelayInMs;
/// Microphone配置
bool? isBluetoothScoEnabled;
bool? isAECEnabled;
bool? isAudioPtsOptimizeEnabled;
bool? isCaptureAudioFrameOnly;
int? sampleRate;
/// MediaRecorder.AudioSource, 设置 MediaRecorder.AudioSource.VOICE_COMMUNICATION
int? audioSource;
/// AudioFormat, 立体声,不是所有手机都有效,设置 AudioFormat.CHANNEL_IN_STEREO
int? channelConfig;
bool? isMuted;
}
// Swift, iOS端参数, 参数名称和七牛直播推流SDK iOS端基本一致
import Foundation
import PLMediaStreamingKit
import AVFoundation
import HappyDNS
class AVStreamingConfig {
/*************** PLVideoCaptureConfiguration ***************/
/**
* 采集的视频数据的帧率,默认为 24
*/
var videoFrameRate: Int? = nil
/**
* 采集的视频的 sessionPreset,默认为 AVCaptureSessionPreset640x480
*/
var sessionPreset: String? = nil
/**
* 前置预览是否开启镜像,默认为 YES 开启
*/
var previewMirrorFrontFacing: Bool? = nil
/**
* 后置预览是否开启镜像,默认为 NO 关闭
*/
var previewMirrorRearFacing: Bool? = nil
/**
* 前置摄像头,推的流是否开启镜像,默认为 NO 关闭
*/
var streamMirrorFrontFacing: Bool? = nil
/**
* 后置摄像头,推的流是否开启镜像,默认为 NO 关闭
*/
var streamMirrorRearFacing: Bool? = nil
/**
* 开启 camera 时的采集摄像头位置,默认为 AVCaptureDevicePositionBack
*/
var position: AVCaptureDevice.Position? = nil
/**
* 开启 camera 时的采集摄像头的旋转方向,默认为 AVCaptureVideoOrientationPortrait
*/
var videoOrientation: AVCaptureVideoOrientation? = nil
/*************** PLAudioCaptureConfiguration ***************/
/**
* 采集音频数据的声道数,默认为 1
* 并非所有采集设备都支持多声道数据的采集,可以通过检查 [AVAudioSession sharedInstance].maximumInputNumberOfChannels 得到当前采集设备支持的最大声道数
*/
var channelsPerFrame: Int? = nil
/**
* 回声消除开关,默认为 NO
* 普通直播用到回声消除的场景不多,当用户开启返听功能,并且使用外放时,可打开这个开关,防止产生尖锐的啸叫声。
*/
var acousticEchoCancellationEnable: Bool? = nil
/*************** PLVideoStreamingConfiguration ***************/
/**
* kPLVideoStreamingQualityLow1
* kPLVideoStreamingQualityLow2
* kPLVideoStreamingQualityLow3
* kPLVideoStreamingQualityMedium1
* kPLVideoStreamingQualityMedium2
* kPLVideoStreamingQualityMedium3
* kPLVideoStreamingQualityHigh1
* kPLVideoStreamingQualityHigh2
* kPLVideoStreamingQualityHigh3
*/
var videoStreamingQuality: String? = nil
/**
* videoProfileLevel
* H.264 编码时使用的 Profile Level。
* 默认情况下使用 AVVideoProfileLevelH264Baseline31,如果对于视频编码有额外的需求并且知晓该参数带来的影响可以自行更改。
* 当你不清楚该参数更改对分辨率要求,码率等影响时,请不要随意更改。
*/
var videoProfileLevel: String? = nil
/**
* videoSize
* 编码时的视频分辨率。
* 需要注意的是,这个参数影响的是视频编码时的分辨率,而非摄像头采集到数据的预览大小,传递给编码器的图像尺寸与此尺寸不同时,会按照 AVVideoScalingModeResizeAspectFill
* 对图像做剪切,从而确保图像不会出现压缩的现象。
*/
var videoSize: CGSize? = nil
/**
* expectedSourceVideoFrameRate
* 预期视频的帧率。
* 预期视频的编码帧率,这个数值对编码器的来说并不是直接限定了 fps, 而是给编码器一个预期的视频帧率,最终编码的视频帧率,是由实际输入的数据决定的。
*/
var expectedSourceVideoFrameRate: Int? = nil
/**
* videoMaxKeyframeInterval
* 视频编码关键帧最大间隔(GOP)。
* h.264 编码时,两个关键帧之间间隔的最多的帧数,一般为 fps 的两倍或者三倍。
*/
var videoMaxKeyframeInterval: Int? = nil
/**
* averageVideoBitRate
* 平均视频编码码率。
* 单位为 bps(Bits per Second)。该参数的视频编码实际过程中,并不是恒定的数值,所以只能设定平均视频编码码率。
*/
var averageVideoBitRate: Int? = nil
/**
* videoEncoderType
* H.264 编码器类型
* 默认采用 PLH264EncoderType_AVFoundation 编码方式,在 iOS 8 及以上的系统可采用 PLH264EncoderType_VideoToolbox。
*/
var videoEncoderType: PLH264EncoderType? = nil
/*************** PLAudioStreamingConfiguration ***************/
/**
* kPLAudioStreamingQualityHigh1
* kPLAudioStreamingQualityHigh2
* kPLAudioStreamingQualityHigh3
*/
var audioStreamingQuality: String? = nil
/**
* 音频编码的采样率, 默认为设备采样率
*/
var encodedAudioSampleRate: PLStreamingAudioSampleRate? = nil
/**
* 音频编码比特率,默认为 96kbps
*/
var audioBitRate: PLStreamingAudioBitRate? = nil
/**
* 编码的声道数,默认为 1
*/
var encodedNumberOfChannels: Int? = nil
/**
* 编码模式,默认为 PLAACEncoderType_iOS_AAC
*/
var audioEncoderType: PLAACEncoderType? = nil
/**
* 输入的音频流描述,默认为单路音频 @[kPLAudioChannelDefault]
* 目前提供两路音频流混音功能,对于ReplayKit录屏推流,若要实现 App Audio 与 Mic Audio 的混音,需设置该属性为 @[kPLAudioChannelApp, kPLAudioChannelMic]
*/
var inputAudioChannelDescriptions: Array<String>? = nil
/**
* PLVideoFillModeStretch: Stretch to fill the full view, which may distort the image outside of its normal aspect ratio
* PLVideoFillModePreserveAspectRatio: Maintains the aspect ratio of the source image, adding bars of the specified background color
* PLVideoFillModePreserveAspectRatioAndFill: Maintains the aspect ratio of the source image, zooming in on its center to fill the view
*/
var fillMode: PLVideoFillModeType? = PLVideoFillModePreserveAspectRatioAndFill
/**
* PLProtocolModel.modelrtmp
* PLProtocolModel.modelsrt
*/
var protocolModel: PLProtocolModel? = PLProtocolModel.modelrtmp
/**
* 自适应码率
*/
var isDynamicFrameEnable: Bool = false
/**
* 自动重连
*/
var isAutoReconnectEnable: Bool = true
/**
* 监听网络切换
*/
var isMonitorNetworkStateEnable: Bool = true
/**
* 回调方法的调用间隔
*/
var statusUpdateInterval: TimeInterval?
/**
* 流信息更新间隔
*/
var threshold: Float?
/**
* 发送队列最大容纳包数量
*/
var maxCount: Int?
/**
* 控制系统屏幕自动锁屏是否关闭
*/
var isIdleTimerDisable: Bool?
/**
*
*/
var isTouchToFocusEnable: Bool?
/**
*
*/
var isSmoothAutoFocusEnabled: Bool?
/**
*
*/
var isPlayback: Bool?
/**
*
*/
var inputGain: Float?
/**
*
*/
var allowAudioMixWithOthers: Bool?
/**
* 最小平均码率
*/
var minVideoBitRate: Int = 0
/**
* iOS/Android 通用参数
*/
var logLevel: Int? = nil
var isLogFileEnabled: Bool = false
var isTorchOn: Bool = false
var publishUrl: String? = nil
var uid: String? = nil
var isQuicEnabled: Bool = false
var isAudioOnly: Bool = false
var isContinuousFocusModeEnabled: Bool = false
var isMuted: Bool = false
/**
* 水印
*/
var watermarkAssertName: String? = nil
var watermarkSize: CGSize? = nil
var watermarkPosition: CGPoint = CGPoint(x: 0, y: 0)
/**
* 美颜
*/
var isBeautifyModeOn: Bool = false
var faceBeautyLevel: Float = 0.6
var faceBeautyWhiten: Float = 0.6
var faceBeautyRedden: Float = 0.6
/**
* DNS配置
*/
var httpDnsServers: Array<String>? = nil
var udpDnsServers: Array<String>? = nil
}
/// AVStreamingView 使用, 可以使用上述Android端和iOS端的参数配置 AVStreamingView
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Center(
child: AVStreamingView(
androidDisableCertificateValidation: true,
//publishUrl: "rtmp://pili-publish.qhdayang.com/testroom2022/t0511?e=1661928820&token=aFpVTdHoT0N5W7lFZqN4UPVMpbx_x6jvU8IlMRNy:yDX3msI5-F9oNiJHiC_OOYkDea0=",
publishUrl: "rtmp://pili-publish.qnsdk.com/sdk-live/bddef867-46ad-4266-91aa-1b876ae709b9?e=1661615426&token=QxZugR8TAhI38AiJ_cptTl3RbzLyca3t-AAiH-Hh:3eFZtUzMRywt0ZmrtLbbuYAWOfo=",
httpDnsServers: const ["https://223.6.6.6/dns-query", "https://8.8.8.8/dns-query"],
udpDnsServers: const ["223.5.5.5", "114.114.114.114", "1.1.1.1", "208.67.222.222"],
onViewCreated: (controller) {
controller.checkAuthentication();
controller.setPublishUrl(url: "rtmp://pili-publish.qnsdk.com/sdk-live/bddef867-46ad-4266-91aa-1b876ae709b9?e=1661615426&token=QxZugR8TAhI38AiJ_cptTl3RbzLyca3t-AAiH-Hh:3eFZtUzMRywt0ZmrtLbbuYAWOfo=");
controller.startStreaming();
},
),
),
),
);
}
更多推荐
已为社区贡献1条内容
所有评论(0)