""" Android net.rtp 包 — AudioGroup, AudioCodec, RtpStream, AudioStream 方法签名完全对齐 Android SDK (此包已废弃但仍是 SDK 的一部分) """ from __future__ import annotations import sys from typing import Any, Dict, List, Optional, Tuple from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) __all__ = [ "AudioGroup", "AudioCodec", "RtpStream", "AudioStream", ] # ═══════════════════════════════════════════════════════════════ # AudioGroup # ═══════════════════════════════════════════════════════════════ class AudioGroup(Stub): """AudioGroup — 音频组 (桌面存根)""" ON_HOLD = 0 MUTED = 1 NORMAL = 2 ECHO_SUPPRESSION = 3 def __init__(self): super().__init__() self._group_mode = AudioGroup.NORMAL self._streams: List["AudioStream"] = [] def clear(self) -> None: """清除所有流""" self._streams.clear() def getGroupMode(self) -> int: """获取组模式""" return self._group_mode def setMode(self, mode: int) -> None: """设置模式""" self._group_mode = mode def sendDtmf(self, digit: int) -> None: """发送 DTMF 音调""" pass def getRtpStream(self, index: int) -> Optional["RtpStream"]: """获取 RTP 流""" if 0 <= index < len(self._streams): return self._streams[index] return None # ═══════════════════════════════════════════════════════════════ # AudioCodec # ═══════════════════════════════════════════════════════════════ class AudioCodec(Stub): """AudioCodec — 音频编解码器 (桌面存根)""" AMR: "AudioCodec" = None PCMA: "AudioCodec" = None PCMU: "AudioCodec" = None GSM_EFR: "AudioCodec" = None MIN_FRAME_SIZE = 1 MAX_FRAME_SIZE = 320 FRAME_COUNT = 8 CODEC_AMR = 0 CODEC_PCMA = 1 CODEC_PCMU = 2 CODEC_GSM_EFR = 3 def __init__(self, type_: int = 0, codec: str = "", codec_spec: str = "", fmtp: str = ""): super().__init__() self._type = type_ self._codec = codec self._codec_spec = codec_spec self._fmtp = fmtp @property def type(self) -> int: """获取类型""" return self._type @property def codec(self) -> str: """获取编解码器名称""" return self._codec @property def codecSpec(self) -> str: """获取编解码器规格""" return self._codec_spec @property def fmtp(self) -> str: """获取 fmtp""" return self._fmtp @staticmethod def getCapabilities() -> List["AudioCodec"]: """获取能力列表""" return [AudioCodec.AMR, AudioCodec.PCMA, AudioCodec.PCMU, AudioCodec.GSM_EFR] @staticmethod def getCodecCapabilities(codec_type: int) -> Optional["AudioCodec"]: """获取指定类型的编解码器能力""" codecs = { AudioCodec.CODEC_AMR: AudioCodec.AMR, AudioCodec.CODEC_PCMA: AudioCodec.PCMA, AudioCodec.CODEC_PCMU: AudioCodec.PCMU, AudioCodec.CODEC_GSM_EFR: AudioCodec.GSM_EFR, } return codecs.get(codec_type) @staticmethod def getEncoder(codec_type: int) -> Optional["AudioCodec"]: """获取编码器""" return AudioCodec.getCodecCapabilities(codec_type) @staticmethod def getDecoder(codec_type: int) -> Optional["AudioCodec"]: """获取解码器""" return AudioCodec.getCodecCapabilities(codec_type) def toString(self) -> str: return f"AudioCodec(type={self._type}, codec={self._codec})" # Initialize AudioCodec constants AudioCodec.AMR = AudioCodec(AudioCodec.CODEC_AMR, "AMR", "AMR/8000", "") AudioCodec.PCMA = AudioCodec(AudioCodec.CODEC_PCMA, "PCMA", "PCMA/8000", "") AudioCodec.PCMU = AudioCodec(AudioCodec.CODEC_PCMU, "PCMU", "PCMU/8000", "") AudioCodec.GSM_EFR = AudioCodec(AudioCodec.CODEC_GSM_EFR, "GSM-EFR", "GSM-EFR/8000", "") # ═══════════════════════════════════════════════════════════════ # RtpStream # ═══════════════════════════════════════════════════════════════ class RtpStream(Stub): """RtpStream — RTP 流 (桌面存根)""" MODE_NORMAL = 0 MODE_SEND_ONLY = 1 MODE_RECEIVE_ONLY = 2 MODE_SEND_RECEIVE = 3 MODE_HOLD = 4 def __init__(self, local_address: str = "127.0.0.1", local_port: int = 5004): super().__init__() self._local_address = local_address self._local_port = local_port self._remote_address = "" self._remote_port = 0 self._mode = RtpStream.MODE_NORMAL self._released = False def getLocalAddress(self) -> str: """获取本地地址""" return self._local_address def getLocalPort(self) -> int: """获取本地端口""" return self._local_port def getRemoteAddress(self) -> str: """获取远程地址""" return self._remote_address def getRemotePort(self) -> int: """获取远程端口""" return self._remote_port def getMode(self) -> int: """获取模式""" return self._mode def setMode(self, mode: int) -> None: """设置模式""" self._mode = mode def associate(self, remote_address: str, remote_port: int) -> None: """关联远程地址端口""" self._remote_address = remote_address self._remote_port = remote_port def release(self) -> None: """释放资源""" self._released = True # ═══════════════════════════════════════════════════════════════ # AudioStream # ═══════════════════════════════════════════════════════════════ class AudioStream(RtpStream): """AudioStream — 音频流 (桌面存根)""" def __init__(self, local_address: str = "127.0.0.1", local_port: int = 5006): super().__init__(local_address, local_port) self._codec: Optional[AudioCodec] = None self._group: Optional[AudioGroup] = None self._dtmf_type: int = -1 def getCodec(self) -> Optional[AudioCodec]: """获取编解码器""" return self._codec def setCodec(self, codec: AudioCodec) -> None: """设置编解码器""" self._codec = codec def getGroup(self) -> Optional[AudioGroup]: """获取音频组""" return self._group def setGroup(self, group: Optional[AudioGroup]) -> None: """设置音频组""" self._group = group def getDtmfType(self) -> int: """获取 DTMF 类型""" return self._dtmf_type def setDtmfType(self, type_: int) -> None: """设置 DTMF 类型""" self._dtmf_type = type_ def join(self, group: AudioGroup) -> None: """加入音频组""" self._group = group def release(self) -> None: super().release()