MicroSIP自定义web拨打协议

需求:通过网页电话号码呼叫指定MicroSIP。

技术调研:MicroSIP支持sip:10086 进行网页调用进行呼叫。

实现:一台电脑安装多个sip,可以自定义Session Initiation Protocol,会话初始协议,可以把sip换成自己任意的ket值,实现不同key值绑定不同的MicroSIP.exe客户端

import tkinter as tk from tkinter import ttk, filedialog, messagebox, simpledialog import os import subprocess import json import sys CONFIG_FILE = "sip_config.json" class SIPProtocolManager: def __init__(self, root): self.root = root self.root.title("SIP 自定义协议管理器") self.root.geometry("720x520") self.root.resizable(True, True) self.config = { "microsip_path": "", "protocols": ["sip2", "fcp"] } self.load_config() self.create_widgets() def create_widgets(self): # === MicroSIP 路径 === path_frame = ttk.Frame(self.root) path_frame.pack(fill=tk.X, padx=10, pady=10) ttk.Label(path_frame, text="MicroSIP.exe 路径:").pack(anchor=tk.W) self.path_var = tk.StringVar(value=self.config["microsip_path"]) path_entry = ttk.Entry(path_frame, textvariable=self.path_var, width=70) path_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 5)) ttk.Button(path_frame, text="浏览...", command=self.browse_microsip).pack(side=tk.RIGHT) # === 协议列表 === proto_frame = ttk.LabelFrame(self.root, text="自定义协议前缀 (如 sip2, fcp)") proto_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5) list_frame = ttk.Frame(proto_frame) list_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5) self.proto_listbox = tk.Listbox(list_frame, selectmode=tk.SINGLE, height=6) self.proto_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.proto_listbox.yview) scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.proto_listbox.config(yscrollcommand=scrollbar.set) for proto in self.config["protocols"]: self.proto_listbox.insert(tk.END, proto) btn_frame = ttk.Frame(proto_frame) btn_frame.pack(fill=tk.X, padx=5, pady=(0, 5)) ttk.Button(btn_frame, text="添加", command=self.add_protocol).pack(side=tk.LEFT, padx=2) ttk.Button(btn_frame, text="删除", command=self.remove_protocol).pack(side=tk.LEFT, padx=2) # === 测试拨号区域 === test_frame = ttk.LabelFrame(self.root, text="测试拨号") test_frame.pack(fill=tk.X, padx=10, pady=5) test_inner = ttk.Frame(test_frame) test_inner.pack(fill=tk.X, padx=10, pady=5) ttk.Label(test_inner, text="测试号码:").pack(side=tk.LEFT) self.test_number_var = tk.StringVar(value="10086") ttk.Entry(test_inner, textvariable=self.test_number_var, width=20).pack(side=tk.LEFT, padx=5) ttk.Button(test_inner, text="拨打测试", command=self.test_dial).pack(side=tk.LEFT, padx=5) # === 底部按钮 === bottom_frame = ttk.Frame(self.root) bottom_frame.pack(fill=tk.X, padx=10, pady=10) ttk.Button(bottom_frame, text="生成注册表文件 (.reg)", command=self.generate_reg).pack(side=tk.LEFT, padx=2) ttk.Button(bottom_frame, text="保存配置", command=self.save_config).pack(side=tk.LEFT, padx=2) def browse_microsip(self): file_path = filedialog.askopenfilename( title="选择 MicroSIP.exe", filetypes=[("Executable files", "*.exe"), ("All files", "*.*")] ) if file_path: # 强制转换为 Windows 反斜杠 file_path = file_path.replace("/", "\\") self.path_var.set(file_path) def add_protocol(self): name = simpledialog.askstring("添加协议", "输入协议前缀(如 sip2, fcp):") if name and name.strip(): name = name.strip() if name not in self.config["protocols"]: self.config["protocols"].append(name) self.proto_listbox.insert(tk.END, name) else: messagebox.showwarning("警告", "该协议已存在!") def remove_protocol(self): sel = self.proto_listbox.curselection() if sel: idx = sel[0] proto = self.proto_listbox.get(idx) self.proto_listbox.delete(idx) self.config["protocols"].remove(proto) else: messagebox.showinfo("提示", "请先选中一个协议") def generate_reg(self): microsip_path = self.path_var.get().strip() if not microsip_path or not os.path.isfile(microsip_path): messagebox.showerror("错误", "请先选择有效的 MicroSIP.exe 路径!") return protocols = self.config["protocols"] if not protocols: messagebox.showwarning("警告", "至少需要一个自定义协议!") return # ✅ 关键修复:正确转义路径 reg_exe_path = microsip_path.replace("/", "\\").replace("\\", "\\\\") reg_content = "Windows Registry Editor Version 5.00\n\n" for proto in protocols: reg_content += f'[HKEY_CLASSES_ROOT\\{proto}]\n' reg_content += f'@="Custom SIP Protocol ({proto})"\n' reg_content += '"URL Protocol"=""\n' reg_content += '"Owner Name"="SIPManager"\n\n' reg_content += f'[HKEY_CLASSES_ROOT\\{proto}\\DefaultIcon]\n' reg_content += f'@="{reg_exe_path},0"\n\n' reg_content += f'[HKEY_CLASSES_ROOT\\{proto}\\shell]\n\n' reg_content += f'[HKEY_CLASSES_ROOT\\{proto}\\shell\\open]\n\n' reg_content += f'[HKEY_CLASSES_ROOT\\{proto}\\shell\\open\\command]\n' # 假设 handler 与 MicroSIP 同目录 handler_path = os.path.join(os.path.dirname(microsip_path), "sip_handler.exe") handler_reg_path = handler_path.replace("/", "\\").replace("\\", "\\\\") reg_content += f'@="\\"{handler_reg_path}\\" \\"%1\\""\n\n' save_path = filedialog.asksaveasfilename( defaultextension=".reg", filetypes=[("Registry files", "*.reg")], title="保存注册表文件" ) if save_path: # ✅ 修复:显式写入 UTF-16 LE BOM import codecs with open(save_path, "wb") as f: f.write(codecs.BOM_UTF16_LE) f.write(reg_content.encode('utf-16-le')) messagebox.showinfo("成功", f"注册表文件已保存到:\n{save_path}") def test_dial(self): number = self.test_number_var.get().strip() if not number: messagebox.showwarning("警告", "请输入测试号码!") return microsip_path = self.path_var.get().strip() if not microsip_path or not os.path.isfile(microsip_path): messagebox.showerror("错误", "MicroSIP 路径无效!") return try: subprocess.Popen([microsip_path, f"sip:{number}"]) messagebox.showinfo("测试拨号", f"已拨打: sip:{number}") except Exception as e: messagebox.showerror("错误", f"启动失败:\n{str(e)}") def save_config(self): self.config["microsip_path"] = self.path_var.get().strip().replace("/", "\\") try: with open(CONFIG_FILE, "w", encoding="utf-8") as f: json.dump(self.config, f, indent=2, ensure_ascii=False) messagebox.showinfo("成功", f"配置已保存到 {CONFIG_FILE}") except Exception as e: messagebox.showerror("错误", f"保存失败:\n{str(e)}") def load_config(self): if os.path.isfile(CONFIG_FILE): try: with open(CONFIG_FILE, "r", encoding="utf-8") as f: loaded = json.load(f) if "microsip_path" in loaded: loaded["microsip_path"] = loaded["microsip_path"].replace("/", "\\") self.config.update(loaded) except: pass # ======================== # 协议处理器(打包后作为 sip_handler.exe) # ======================== def protocol_handler(): if len(sys.argv) < 2: return uri = sys.argv[1] if ":" not in uri: return _, number = uri.split(":", 1) if not number: return # 从 handler 所在目录找 MicroSIP.exe base_dir = os.path.dirname(os.path.abspath(sys.executable)) microsip = os.path.join(base_dir, "MicroSIP.exe") if os.path.isfile(microsip): try: subprocess.Popen([microsip, f"sip:{number}"]) except: pass if __name__ == "__main__": if len(sys.argv) >= 2 and (":" in sys.argv[1]): protocol_handler() else: root = tk.Tk() app = SIPProtocolManager(root) root.mainloop()

代码打包以后会变成sip_handler.exe。

使用方法:

1、选择呼叫客户端

2、添加协议前缀

3、生成注册表

4、保存配置

5、注入注册表

6、网页呼叫 自定义 的前缀:电话号码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1195395.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

桥式起重机远程运维管理系统方案

一、行业背景桥式起重机是港口、物流园区、工厂车间等场所广泛使用的大型起重搬运设备&#xff0c;主要负责各类货物的装卸、转运与堆存作业。其运行稳定性直接关系到港口作业效率、仓储物流周转能力及生产线的连续性。在实际应用场景中&#xff0c;桥式起重机常需与堆场设备、…

为什么顶级AI项目都在转向MCP协议?揭开本地文件操作的安全黑箱

第一章&#xff1a;为什么顶级AI项目都在转向MCP协议&#xff1f;揭开本地文件操作的安全黑箱 在AI模型训练和部署过程中&#xff0c;本地文件系统的安全访问长期被视为“理所当然”的底层能力。然而&#xff0c;随着数据泄露事件频发&#xff0c;传统文件读写机制的脆弱性逐渐…

Qt 6 所有 QML 类型(官方完整清单 · 原始索引版)

来源&#xff1a; https://doc.qt.io/qt-6/zh/qmltypes.html 所有 QML 类型&#xff08;A–Z&#xff09; A Abstract3DAxis Abstract3DSeries AbstractActionInput AbstractAnimation AbstractAxis AbstractAxis3D AbstractAxisInput AbstractBarSeries AbstractButton Abst…

强声定向广播扬声器在高速公路道路应急指挥车上的集成应用

强声定向广播扬声器集成到道路应急指挥车上&#xff0c;极大地提升了现场指挥、警示和疏导的效能&#xff0c;是现代化应急指挥体系中的重要装备。一、 核心应用价值与优势突破环境噪音&#xff0c;直达目标区域&#xff1a;在高速公路上&#xff0c;背景噪音&#xff08;风声、…

PyTorch-2.x镜像为何快?阿里源加速下载实战评测

PyTorch-2.x镜像为何快&#xff1f;阿里源加速下载实战评测 1. 镜像到底快在哪&#xff1f;不只是预装那么简单 你有没有经历过这样的场景&#xff1a;刚搭好GPU服务器&#xff0c;第一件事就是 pip install torch torchvision torchaudio&#xff0c;然后眼睁睁看着进度条卡…

郑州超级学长怎么样?2026年雅思托福培训真实反馈

在郑州地区,雅思、托福等出国语言考试培训需求持续增长,许多学习者希望找到教学质量可靠、课程体系完善的机构。选择合适的培训机构需要综合考虑课程设置、师资力量、学习效果等多方面因素,以下为郑州地区部分语言培…

GPEN紫蓝渐变UI设计亮点解析:用户体验优化实战案例

GPEN紫蓝渐变UI设计亮点解析&#xff1a;用户体验优化实战案例 1. 引言&#xff1a;从工具到体验的升级 你有没有遇到过这种情况&#xff1f;好不容易找到一个功能强大的AI图像修复工具&#xff0c;结果打开界面后一脸懵——按钮乱糟糟、参数看不懂、操作流程像迷宫。很多技术…

实时可视化:Emotion2Vec+ Large情感波动图表生成教程

实时可视化&#xff1a;Emotion2Vec Large情感波动图表生成教程 1. 引言&#xff1a;让声音的情绪“看得见” 你有没有想过&#xff0c;一段语音里藏着多少情绪变化&#xff1f;是平静中突然的激动&#xff0c;还是悲伤里夹杂着一丝希望&#xff1f;过去&#xff0c;我们只能…

基于贝叶斯优化BP神经网络与MGWO算法的氧化锆陶瓷磨削工艺参数优化附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。 &#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室 &#x1f447; 关注我领取海量matlab电子书和数学建模资料 &#…

CAM++说话人验证不准确?相似度阈值调优实战指南

CAM说话人验证不准确&#xff1f;相似度阈值调优实战指南 1. 为什么你的CAM说话人验证结果总不准&#xff1f; 你是不是也遇到过这种情况&#xff1a;用CAM做说话人验证&#xff0c;明明是同一个人的两段语音&#xff0c;系统却判定“不是同一人”&#xff1b;或者反过来&…

Paraformer识别结果复制不便?浏览器兼容性优化使用建议

Paraformer识别结果复制不便&#xff1f;浏览器兼容性优化使用建议 1. 问题背景与使用痛点 在使用 Speech Seaco Paraformer ASR 进行中文语音识别时&#xff0c;很多用户反馈&#xff1a;虽然识别效果出色、界面简洁易用&#xff0c;但在实际操作中却遇到了一个看似“小”但…

Dify插件选型难题终结者:2026年实战验证的6款高效能插件推荐

第一章&#xff1a;Dify插件市场2026年有哪些好用的插件 随着AI应用生态的持续演进&#xff0c;Dify插件市场在2026年迎来了功能更强大、集成更智能的工具集合。开发者和企业用户可通过这些插件快速扩展AI工作流能力&#xff0c;实现自动化决策、多模态交互与系统级集成。 智能…

快看!AI赋能的智慧康养,用科技为晚年生活添一份安心

朋友们&#xff0c;你们是否跟我一样在对长辈的康养方面愈发重视&#xff0c;既要保障安全无忧&#xff0c;又要兼顾情感陪伴&#xff0c;京能天云数据推出的智慧康养服务 APP&#xff0c;以 “科技守护健康&#xff0c;陪伴温暖生活” 为初心&#xff0c;将 AI 智能与适老化设…

Three_Phase_SPWM_THIPWM_Inverter:基于MATLAB/Simul...

Three_Phase_SPWM_THIPWM_Inverter&#xff1a;基于MATLAB/Simulink的三相SPWM逆变器和三相THIPWM逆变器仿真模型。 仿真条件&#xff1a;MATLAB/Simulink R2015b打开Simulink新建模型时&#xff0c;很多人会被三相逆变器的PWM调制搞到头秃。今天咱们用2015b版本实操两种经典调…

并发编程 - ThreadLocal 线程本地变量

知识点 12:并发编程 —— ThreadLocal 线程本地变量 1. 是什么?它解决了什么问题? ThreadLocal 是 Java 提供的一个非常独特的解决线程安全问题的工具,它提供了一种全新的思路:不共享,即安全。 它的核心思想是:…

AI绘画趋势一文详解:Z-Image-Turbo等开源模型部署方式演进

AI绘画趋势一文详解&#xff1a;Z-Image-Turbo等开源模型部署方式演进 你有没有想过&#xff0c;只需要几行命令和一个浏览器&#xff0c;就能在本地运行一个强大的AI绘画工具&#xff1f;如今&#xff0c;像 Z-Image-Turbo 这样的开源图像生成模型正在让这一切变得轻而易举。…

Live Avatar新手必看:首次运行常见问题解决指南

Live Avatar新手必看&#xff1a;首次运行常见问题解决指南 1. 引言&#xff1a;快速上手前的必要准备 你刚下载了Live Avatar这个由阿里联合高校开源的数字人项目&#xff0c;满心期待地想要生成一个属于自己的虚拟形象视频。但一运行就遇到显存不足、进程卡死、NCCL报错等问…

并发请求支持多少?API吞吐量基准部署教程

并发请求支持多少&#xff1f;API吞吐量基准部署教程 1. 功能概述 本工具基于阿里达摩院 ModelScope 的 DCT-Net 模型&#xff0c;支持将真人照片转换为卡通风格。 支持的功能&#xff1a; 单张图片卡通化转换批量多张图片处理多种风格选择&#xff08;当前支持标准卡通风格…

吐血推荐!专科生毕业论文必备的10个AI论文平台

吐血推荐&#xff01;专科生毕业论文必备的10个AI论文平台 2026年专科生论文写作工具测评&#xff1a;为什么你需要一份精准指南 随着AI技术在学术领域的深入应用&#xff0c;越来越多的专科生开始依赖智能写作工具来提升论文效率与质量。然而&#xff0c;面对市场上五花八门的…

国外期刊怎么找:实用查找方法与途径指南

刚开始做科研的时候&#xff0c;我一直以为&#xff1a; 文献检索就是在知网、Google Scholar 里反复换关键词。 直到后来才意识到&#xff0c;真正消耗精力的不是“搜不到”&#xff0c;而是—— 你根本不知道最近这个领域发生了什么。 生成式 AI 出现之后&#xff0c;学术检…