feat: ios添加录音相关功能
This commit is contained in:
parent
026212c5b5
commit
ea2000af96
@ -314,7 +314,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const jumpToPlayer = async () => {
|
const jumpToPlayer = async () => {
|
||||||
// #ifdef APP-ANDROID
|
// #ifdef APP-PLUS
|
||||||
// 检查权限
|
// 检查权限
|
||||||
const result = await requestPermission()
|
const result = await requestPermission()
|
||||||
if (result.code !== 0) {
|
if (result.code !== 0) {
|
||||||
|
|||||||
@ -193,7 +193,7 @@
|
|||||||
stopServiceFunction,
|
stopServiceFunction,
|
||||||
runSendServiceFunction,
|
runSendServiceFunction,
|
||||||
stopSendServiceFunction,
|
stopSendServiceFunction,
|
||||||
dataSend
|
dataSendFunction
|
||||||
} from '@/uni_modules/xhj-tencent-xp2p'
|
} from '@/uni_modules/xhj-tencent-xp2p'
|
||||||
import { initAudio, onStartRecord, stopRecord, releaseRecord } from '@/uni_modules/xhj-record'
|
import { initAudio, onStartRecord, stopRecord, releaseRecord } from '@/uni_modules/xhj-record'
|
||||||
// #endif
|
// #endif
|
||||||
@ -224,6 +224,7 @@
|
|||||||
const isMute = ref(false)
|
const isMute = ref(false)
|
||||||
const isVideoLoaded = ref(false)
|
const isVideoLoaded = ref(false)
|
||||||
const videoKey = ref(Date.now())
|
const videoKey = ref(Date.now())
|
||||||
|
const cleanupCalled = ref(false)
|
||||||
|
|
||||||
const advancedOptions = ref([
|
const advancedOptions = ref([
|
||||||
{
|
{
|
||||||
@ -249,6 +250,34 @@
|
|||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const cleanupResources = () => {
|
||||||
|
if (cleanupCalled.value) return
|
||||||
|
cleanupCalled.value = true
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
// 停止录音
|
||||||
|
url.value = null
|
||||||
|
isVideoLoaded.value = false
|
||||||
|
if (isVoice.value) {
|
||||||
|
stopRecord()
|
||||||
|
}
|
||||||
|
releaseRecord()
|
||||||
|
if (deviceInfo.value) {
|
||||||
|
stopSendServiceFunction(`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`)
|
||||||
|
stopServiceFunction(`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`)
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
const page = getCurrentPages().pop()
|
||||||
|
if (page) {
|
||||||
|
const player = page.selectComponent('#playerRef')
|
||||||
|
if (player && player.stopAll) {
|
||||||
|
player.stopAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// #ifdef APP-PLUS
|
// #ifdef APP-PLUS
|
||||||
initAudio()
|
initAudio()
|
||||||
@ -307,7 +336,7 @@
|
|||||||
runSendServiceFunction(
|
runSendServiceFunction(
|
||||||
`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`,
|
`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`,
|
||||||
'channel=0',
|
'channel=0',
|
||||||
true
|
false
|
||||||
)
|
)
|
||||||
}, 0)
|
}, 0)
|
||||||
} else {
|
} else {
|
||||||
@ -320,19 +349,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
onUnload(() => {
|
onUnload(() => {
|
||||||
// #ifdef APP-PLUS
|
cleanupResources()
|
||||||
// 停止录音
|
|
||||||
releaseRecord()
|
|
||||||
stopSendServiceFunction(`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`)
|
|
||||||
stopServiceFunction(`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`)
|
|
||||||
// #endif
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
const page = getCurrentPages().pop()
|
|
||||||
const player = page.selectComponent('#playerRef')
|
|
||||||
if (player.stopAll) {
|
|
||||||
player.stopAll()
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const showQualitySelector = () => {
|
const showQualitySelector = () => {
|
||||||
@ -384,13 +401,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleHangUp = () => {
|
const handleHangUp = () => {
|
||||||
// #ifdef MP-WEIXIN
|
cleanupResources()
|
||||||
const page = getCurrentPages().pop()
|
|
||||||
const player = page.selectComponent('#playerRef')
|
|
||||||
if (player.stopAll) {
|
|
||||||
player.stopAll()
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
uni.navigateBack()
|
uni.navigateBack()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -535,7 +546,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const callback = audioData => {
|
const callback = audioData => {
|
||||||
dataSend(`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`, audioData)
|
dataSendFunction(`${deviceInfo.value.productId}/${deviceInfo.value.deviceName}`, audioData)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePlaySuccess = () => {
|
const handlePlaySuccess = () => {
|
||||||
|
|||||||
8
uni_modules/xhj-record/utssdk/app-ios/Info.plist
Normal file
8
uni_modules/xhj-record/utssdk/app-ios/Info.plist
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
|
<string>需要访问麦克风进行录音</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
244
uni_modules/xhj-record/utssdk/app-ios/hybrid.swift
Normal file
244
uni_modules/xhj-record/utssdk/app-ios/hybrid.swift
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
import Foundation
|
||||||
|
import AVFoundation
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public class RecordPermission: NSObject {
|
||||||
|
@objc
|
||||||
|
public static func requestRecordPermission(_ completion: @escaping (Bool) -> Void) {
|
||||||
|
AVAudioSession.sharedInstance().requestRecordPermission { granted in
|
||||||
|
completion(granted)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public class AudioRecorderManager: NSObject {
|
||||||
|
private var audioEngine: AVAudioEngine?
|
||||||
|
private var audioConverter: AVAudioConverter?
|
||||||
|
private var aacBuffer: AVAudioCompressedBuffer?
|
||||||
|
|
||||||
|
private let lock = NSLock()
|
||||||
|
private var _isRecording = false
|
||||||
|
var isRecording: Bool {
|
||||||
|
get {
|
||||||
|
lock.lock()
|
||||||
|
defer { lock.unlock() }
|
||||||
|
return _isRecording
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
lock.lock()
|
||||||
|
_isRecording = newValue
|
||||||
|
lock.unlock()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public static let shared = AudioRecorderManager()
|
||||||
|
|
||||||
|
private override init() {}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public func initAudio(_ completion: @escaping (Bool, String) -> Void) {
|
||||||
|
completion(true, "Module initialized")
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public func startRecord(_ completion: @escaping (Data?, Bool, String) -> Void) {
|
||||||
|
if self.isRecording {
|
||||||
|
completion(nil, false, "Recording is already in progress.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let session = AVAudioSession.sharedInstance()
|
||||||
|
do {
|
||||||
|
try session.setCategory(.playAndRecord, mode: .default, options: .defaultToSpeaker)
|
||||||
|
try session.setPreferredSampleRate(16000.0)
|
||||||
|
try session.setPreferredInputNumberOfChannels(1)
|
||||||
|
try session.setActive(true)
|
||||||
|
} catch {
|
||||||
|
completion(nil, false, "Failed to set up audio session: \(error.localizedDescription)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
audioEngine = AVAudioEngine()
|
||||||
|
guard let audioEngine = audioEngine else {
|
||||||
|
completion(nil, false, "Failed to create audio engine")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let inputNode = audioEngine.inputNode
|
||||||
|
let inputFormat = inputNode.outputFormat(forBus: 0)
|
||||||
|
|
||||||
|
var outputFormatDescription = AudioStreamBasicDescription(
|
||||||
|
mSampleRate: 16000.0,
|
||||||
|
mFormatID: kAudioFormatMPEG4AAC,
|
||||||
|
mFormatFlags: 2,
|
||||||
|
mBytesPerPacket: 0,
|
||||||
|
mFramesPerPacket: 1024,
|
||||||
|
mBytesPerFrame: 0,
|
||||||
|
mChannelsPerFrame: 1,
|
||||||
|
mBitsPerChannel: 0,
|
||||||
|
mReserved: 0
|
||||||
|
)
|
||||||
|
|
||||||
|
guard let outputFormat = AVAudioFormat(streamDescription: &outputFormatDescription) else {
|
||||||
|
completion(nil, false, "Failed to create output audio format")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let converter = AVAudioConverter(from: inputFormat, to: outputFormat) else {
|
||||||
|
completion(nil, false, "Failed to create audio converter")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.audioConverter = converter
|
||||||
|
|
||||||
|
self.aacBuffer = AVAudioCompressedBuffer(
|
||||||
|
format: outputFormat,
|
||||||
|
packetCapacity: 1,
|
||||||
|
maximumPacketSize: converter.maximumOutputPacketSize
|
||||||
|
)
|
||||||
|
|
||||||
|
inputNode.installTap(onBus: 0, bufferSize: 1024, format: inputFormat) { [weak self] (pcmBuffer, when) in
|
||||||
|
guard let self = self, self.isRecording else { return }
|
||||||
|
self.convert(pcmBuffer: pcmBuffer, completion: completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
audioEngine.prepare()
|
||||||
|
try audioEngine.start()
|
||||||
|
self.isRecording = true
|
||||||
|
completion(nil, true, "Recording started")
|
||||||
|
} catch {
|
||||||
|
self.isRecording = false
|
||||||
|
completion(nil, false, "Failed to start audio engine: \(error.localizedDescription)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func convert(pcmBuffer: AVAudioPCMBuffer, completion: @escaping (Data?, Bool, String) -> Void) {
|
||||||
|
guard let converter = self.audioConverter, let outputBuffer = self.aacBuffer else { return }
|
||||||
|
|
||||||
|
outputBuffer.byteLength = 0
|
||||||
|
outputBuffer.packetCount = 0
|
||||||
|
|
||||||
|
var error: NSError?
|
||||||
|
var pcmBufferWasProvided = false
|
||||||
|
let status = converter.convert(to: outputBuffer, error: &error) { _, outStatus in
|
||||||
|
if pcmBufferWasProvided {
|
||||||
|
outStatus.pointee = .noDataNow
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
outStatus.pointee = .haveData
|
||||||
|
pcmBufferWasProvided = true
|
||||||
|
return pcmBuffer
|
||||||
|
}
|
||||||
|
|
||||||
|
guard status != .error, error == nil else {
|
||||||
|
print("AAC conversion error: \(error?.localizedDescription ?? "unknown")")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if outputBuffer.byteLength == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let aacData = Data(bytes: outputBuffer.data, count: Int(outputBuffer.byteLength))
|
||||||
|
|
||||||
|
guard let adtsHeader = self.adtsHeader(for: aacData.count) else {
|
||||||
|
print("Failed to create ADTS header")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var fullPacket = Data()
|
||||||
|
fullPacket.append(Data(adtsHeader))
|
||||||
|
fullPacket.append(aacData)
|
||||||
|
|
||||||
|
completion(fullPacket, true, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
private func adtsHeader(for aacFrameSize: Int) -> [UInt8]? {
|
||||||
|
guard let outputFormat = self.audioConverter?.outputFormat else { return nil }
|
||||||
|
|
||||||
|
let adtsLength = aacFrameSize + 7
|
||||||
|
let sampleRate = outputFormat.sampleRate
|
||||||
|
let channels = outputFormat.channelCount
|
||||||
|
|
||||||
|
let sampleRateIndices: [Double: Int] = [
|
||||||
|
96000: 0, 88200: 1, 64000: 2, 48000: 3, 44100: 4, 32000: 5,
|
||||||
|
24000: 6, 22050: 7, 16000: 8, 12000: 9, 11025: 10, 8000: 11, 7350: 12
|
||||||
|
]
|
||||||
|
guard let freqIndex = sampleRateIndices[sampleRate] else {
|
||||||
|
print("Unsupported sample rate for ADTS header: \(sampleRate)")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
let profile = 2 // AAC-LC
|
||||||
|
let channelCfg = channels
|
||||||
|
|
||||||
|
var adtsHeader = [UInt8](repeating: 0, count: 7)
|
||||||
|
adtsHeader[0] = 0xFF
|
||||||
|
adtsHeader[1] = 0xF9
|
||||||
|
adtsHeader[2] = UInt8(((profile - 1) << 6) | (freqIndex << 2) | (Int(channelCfg) >> 2))
|
||||||
|
adtsHeader[3] = UInt8((Int(channelCfg) & 3) << 6 | (adtsLength >> 11))
|
||||||
|
adtsHeader[4] = UInt8((adtsLength & 0x7FF) >> 3)
|
||||||
|
adtsHeader[5] = UInt8(((adtsLength & 7) << 5) | 0x1F)
|
||||||
|
adtsHeader[6] = 0xFC
|
||||||
|
|
||||||
|
return adtsHeader
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public func stopRecord(_ completion: @escaping (Bool, String, String) -> Void) {
|
||||||
|
guard self.isRecording else {
|
||||||
|
completion(false, "Recording is not in progress.", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.isRecording = false
|
||||||
|
|
||||||
|
audioEngine?.stop()
|
||||||
|
audioEngine?.inputNode.removeTap(onBus: 0)
|
||||||
|
audioEngine = nil
|
||||||
|
audioConverter = nil
|
||||||
|
aacBuffer = nil
|
||||||
|
|
||||||
|
do {
|
||||||
|
try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
|
||||||
|
} catch {
|
||||||
|
print("Failed to deactivate audio session: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(true, "Recording stopped", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public func releaseRecord(_ completion: @escaping (Bool, String) -> Void) {
|
||||||
|
if self.isRecording {
|
||||||
|
self.isRecording = false
|
||||||
|
audioEngine?.stop()
|
||||||
|
audioEngine?.inputNode.removeTap(onBus: 0)
|
||||||
|
}
|
||||||
|
audioEngine = nil
|
||||||
|
audioConverter = nil
|
||||||
|
aacBuffer = nil
|
||||||
|
|
||||||
|
do {
|
||||||
|
try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
|
||||||
|
} catch {
|
||||||
|
print("Failed to deactivate audio session on release: \(error)")
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(true, "Record released")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public class UTSConversionHelper: NSObject {
|
||||||
|
@objc
|
||||||
|
public static func dataToNSArray(_ data: Data) -> NSArray {
|
||||||
|
let byteArray = [UInt8](data)
|
||||||
|
let nsArray = NSMutableArray()
|
||||||
|
for byte in byteArray {
|
||||||
|
nsArray.add(NSNumber(value: byte))
|
||||||
|
}
|
||||||
|
return nsArray
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,85 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
// @ts-nocheck
|
||||||
|
// @ts-ignore-start
|
||||||
|
|
||||||
|
import { Result } from '../interface.uts'
|
||||||
|
|
||||||
|
function dataToByteArray(data: Data): Array<UInt8> {
|
||||||
|
const nsArray = UTSConversionHelper.dataToNSArray(data)
|
||||||
|
const buffer: Array<UInt8> = []
|
||||||
|
if (nsArray != null) {
|
||||||
|
for (const item of nsArray) {
|
||||||
|
const num = item as NSNumber
|
||||||
|
buffer.push(num.uint8Value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
export const requestPermission = async function (): Promise<Result> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
RecordPermission.requestRecordPermission((granted: boolean) => {
|
||||||
|
if (granted) {
|
||||||
|
resolve({ code: 0, data: {}, message: '成功' })
|
||||||
|
} else {
|
||||||
|
resolve({ code: -1, data: {}, message: '失败' })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const initAudio = async function (): Promise<Result> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
AudioRecorderManager.shared.initAudio((success: boolean, message: string) => {
|
||||||
|
if (success) {
|
||||||
|
resolve({ code: 0, data: {}, message: message })
|
||||||
|
} else {
|
||||||
|
resolve({ code: -1, data: {}, message: message })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function onStartRecord(callback: (data: Array<UInt8>) => void): Promise<Result> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
AudioRecorderManager.shared.startRecord(
|
||||||
|
(data: Data | null, success: boolean, message: string) => {
|
||||||
|
if (data != null) {
|
||||||
|
callback(dataToByteArray(data!))
|
||||||
|
} else if (success) {
|
||||||
|
resolve({ code: 0, data: {}, message: message })
|
||||||
|
} else {
|
||||||
|
resolve({ code: -1, data: {}, message: message })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const stopRecord = async function (): Promise<Result> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
AudioRecorderManager.shared.stopRecord(
|
||||||
|
(success: boolean, message: string, filePath: string) => {
|
||||||
|
if (success) {
|
||||||
|
resolve({ code: 0, data: { filePath: filePath }, message: message })
|
||||||
|
} else {
|
||||||
|
resolve({ code: -1, data: {}, message: message })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const releaseRecord = async function (): Promise<Result> {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
AudioRecorderManager.shared.releaseRecord((success: boolean, message: string) => {
|
||||||
|
if (success) {
|
||||||
|
resolve({ code: 0, data: {}, message: message })
|
||||||
|
} else {
|
||||||
|
resolve({ code: -1, data: {}, message: message })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore-end
|
||||||
@ -158,7 +158,7 @@ export const stopSendServiceFunction = async function (id: string): Promise<Resu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dataSend = async function (id: string, data: Array<number>): Promise<Result> {
|
export const dataSendFunction = async function (id: string, data: Array<number>): Promise<Result> {
|
||||||
try {
|
try {
|
||||||
let byteArray = new ByteArray(data.length.toInt())
|
let byteArray = new ByteArray(data.length.toInt())
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,30 @@ public class P2PConversionHelper: NSObject {
|
|||||||
guard let pointer = cString else {
|
guard let pointer = cString else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// Use explicit UTF-8 encoding for safety, especially with URLs.
|
|
||||||
return String(cString: pointer, encoding: .utf8)
|
return String(cString: pointer, encoding: .utf8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public class XP2PDataHelper: NSObject {
|
||||||
|
@objc
|
||||||
|
public static func createBytes(_ array: NSArray) -> UnsafeMutablePointer<UInt8>? {
|
||||||
|
let count = array.count
|
||||||
|
guard count > 0 else { return nil }
|
||||||
|
|
||||||
|
let pointer = UnsafeMutablePointer<UInt8>.allocate(capacity: count)
|
||||||
|
for i in 0..<count {
|
||||||
|
if let number = array[i] as? NSNumber {
|
||||||
|
pointer[i] = number.uint8Value
|
||||||
|
} else {
|
||||||
|
pointer[i] = 0 // Default value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc
|
||||||
|
public static func deallocateBytes(_ pointer: UnsafeMutablePointer<UInt8>?) {
|
||||||
|
pointer?.deallocate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -74,7 +74,7 @@ export const startServiceFunction = async function (
|
|||||||
config.cross = true
|
config.cross = true
|
||||||
|
|
||||||
// 设置回调
|
// 设置回调
|
||||||
setUserCallbackToXp2p(avRecvHandle, msgHandle, deviceDataHandle)
|
setUserCallbackToXp2p(null, msgHandle, null)
|
||||||
|
|
||||||
const result = startService(deviceId, productId, deviceName, config)
|
const result = startService(deviceId, productId, deviceName, config)
|
||||||
|
|
||||||
@ -132,8 +132,8 @@ export const runSendServiceFunction = async function (
|
|||||||
crypto: boolean
|
crypto: boolean
|
||||||
): Promise<Result> {
|
): Promise<Result> {
|
||||||
try {
|
try {
|
||||||
// const result = await runSendService(id, cmd, crypto)
|
const result = runSendService(id, cmd, crypto)
|
||||||
// console.log('开始发送服务', result)
|
console.log('开始发送服务', result)
|
||||||
return {
|
return {
|
||||||
code: 0,
|
code: 0,
|
||||||
data: {},
|
data: {},
|
||||||
@ -150,9 +150,39 @@ export const runSendServiceFunction = async function (
|
|||||||
|
|
||||||
export const stopSendServiceFunction = async function (id: string): Promise<Result> {
|
export const stopSendServiceFunction = async function (id: string): Promise<Result> {
|
||||||
try {
|
try {
|
||||||
// const nullPointer = P2PPointerHelper.createNullPointer()
|
const result = stopSendService(id, null)
|
||||||
// const result = await stopSendService(id, nullPointer)
|
console.log('停止发送服务', result)
|
||||||
// console.log('停止发送服务', result)
|
return {
|
||||||
|
code: 0,
|
||||||
|
data: {},
|
||||||
|
message: '成功'
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
data: {},
|
||||||
|
message: error.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const dataSendFunction = async function (id: string, data: Array<number>): Promise<Result> {
|
||||||
|
const buffer = XP2PDataHelper.createBytes(data as NSArray)
|
||||||
|
|
||||||
|
if (buffer == null) {
|
||||||
|
return {
|
||||||
|
code: -1,
|
||||||
|
data: {},
|
||||||
|
message: '创建数据缓冲区失败'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = dataSend(id, buffer, data.length)
|
||||||
|
// console.log('发送数据结果', result)
|
||||||
|
|
||||||
|
XP2PDataHelper.deallocateBytes(buffer)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
code: 0,
|
code: 0,
|
||||||
data: {},
|
data: {},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user