中国首位“女变男”变性人:从争议到重生,他如今活成了这样。
在中国,跨性别群体的权益和生存状况长期以来鲜少被公众关注,尤其是女性-to-男性(FtM)的变性者,往往比男变女(MtF)更加隐形。然而,早在21世纪初,就有一位勇敢者——耿子(原名耿兰俊),成为中国首位公开完成女变男性别重置手术的跨性别男性。
近20年过去了,这位曾经的“中国第一人”,如今过着怎样的生活?

从“她”到“他”:艰难的蜕变之路
耿子出生于一个普通家庭,从小便对自己的性别身份感到困惑。在90年代的中国,社会对跨性别群体的认知几乎为零,医学和法律的支持更是匮乏。尽管如此,耿子仍然坚定地走上了性别重置的道路。
2005年前后,他接受了胸部切除手术(Top Surgery)和激素治疗,并逐步完成了法律上的性别变更。由于当时国内对FtM手术的经验较少,耿子的每一步都充满挑战,甚至面临医疗风险和社会歧视。耿子的故事被媒体报道后,引发了广泛讨论。2006年,纪录片《子非鱼》记录了他的生活片段,让更多人了解到跨性别男性的真实处境。然而,媒体的曝光也带来了巨大的压力,家人曾难以接受,朋友疏远,甚至求职时遭遇歧视。

如今近20年过去,耿子已淡出公众视野,选择了一种低调的生活方式。据知情人士透露,他目前定居在国内某城市,从事技术类工作,身边有理解和支持他的朋友。
尽管不再活跃于媒体,耿子偶尔会在跨性别社群里分享经验,鼓励年轻一代的FtM勇敢面对自我。他曾说:“我不后悔自己的选择,因为只有活成真正的自己,人生才有意义。”

耿子的经历是中国跨性别权益发展的一个缩影。如今,虽然社会认知有所进步,但跨性别者仍面临诸多挑战:
医疗障碍:性别重置手术费用高昂,且部分医院仍设置严格门槛。
法律困境:更改身份证性别需完成特定手术,对部分跨性别者构成负担。
社会偏见:职场歧视、家庭排斥等问题依然存在。
不过,近年来,越来越多的跨性别者开始发声,社会支持网络也在逐步建立。耿子作为早期的开拓者,他的勇气为后来者铺平了道路。
在中国,像耿子这样的跨性别者还有很多,他们的声音值得被听见,他们的权利值得被尊重。未来,希望社会能给予更多理解与支持,让每个人都能活出真实的模样。
“iOS自带播放器不堪重用,我花15周从头开发了个离线替代品!”
在移动应用开发日益依赖云服务与框架的今天,一位独立开发者却选择回归本地、离线优先的设计初衷:用 1.5 周时间打造一款简洁的 iOS 音乐播放器。
谈及为什么要自己动手开发时,其在博客上表示:“2025 年,在 iPhone 上想听自己收藏的音乐竟然变得挺麻烦的。要么掏钱给苹果,要么得绕过一堆限制,挺烦的。于是我干脆从头写了一个自己的音乐播放器,能全文搜索、支持 iCloud,还优先本地播放。”
与此同时,他还将这个项目在 GitHub 上开源了出来,供更多的开发者参考:https://github.com/nexo-tech/music-app
原文链接:https://nexo.sh/posts/why-i-built-a-native-mp3-player-in-swiftui/
作者 | Oleg Pustovit编译 | 苏宓出品 | CSDN(ID:CSDNnews)以下为译文:
为什么要自己动手开发一款播放器?
和很多人一样,我是那种会不知不觉订阅了一堆服务的人,有些是通过苹果官方渠道买的(比如 iCloud、Apple Music),还有一些是在其他平台上糊里糊涂续费的(像 Netflix,我居然都忘了还在付钱)。我其实也常用 Apple Music(之前也用过 Spotify),但后来发现流媒体听歌其实只是图个方便,真说不上是刚需。我自己整理了一个本地音乐库后,也没觉得损失什么,反倒不用被平台绑定了。
一开始我以为,取消 Apple Music 后还能继续用 iCloud 音乐库同步歌曲,结果一取消订阅,同步功能也没了——原来这功能是要钱的。虽然可以通过 iTunes Match(每年 24.99 美元)重新开通,但本质上只是把 256kbps 的 AAC 文件传上云端,原始音质的文件还是留在你设备上,除非你自己手动替换。现在的 Mac 上,这一切都要在 Music App 里操作。如果你一个会员都不买,那同步功能就彻底没戏了,只能靠连线或 Wi-Fi 手动同步。
我实在受够了这些限制,就决定自己动手。
如果我买了个计算设备(这里是 iPhone),那我为什么不能用代码把它变成我想用的样子呢?我想做的其实很简单:能加载音乐、整理它们、正常播放,顺便也提醒一下自己——iPhone 其实还是一台通用电脑,我应该有权自己决定怎么用它。
现在 Apple 和其他软件的现状
在开始写自己的 App 之前,我也先去研究了一下官方和第三方有哪些听本地音乐的方案。
Apple 自带的应用
从技术上讲,你可以在「文件」App 里直接播放 iCloud 里的音乐,但它根本不是为听歌设计的。没有播放列表、没有标签整理、没有播放队列……虽然勉强能放歌,但体验非常差,几乎没法用。
第三方 App
我去 App Store 找了一圈,虽然有不少看起来不错的 App,但很多都要订阅付费。说实话,这种只播放本地音乐的 App,搞订阅制真有点说不过去。
有一个叫 Doppler 的 App 我还挺喜欢的,试用了一下,它的界面主要围绕「专辑」来组织,搜索功能不太行,从 iCloud 导入音乐也挺慢,而且处理层级多的文件夹时特别麻烦。不过好的一点是,它是一次性买断,不搞订阅。
自己动手:技术折腾过程
于是我决定亲手做一个满足我需求的理想播放器:
可以在 iCloud 文件夹里全文搜索音乐,快速选中并导入;
至少要有跟官方音乐 App 差不多的功能:播放队列、播放列表、按专辑整理等等;
界面要顺手、看着舒服。
一开始试了 React Native
一开始我没用 Swift,因为之前用过一次,感觉不太好。当时虽然它的语法挺像 TypeScript,也有点 Rust 那种内存安全的风格,但那时候没有原生的 async/await,用起来比 Go 或 JS/TS 写并发代码麻烦多了,得写一堆模板代码,让人挺沮丧的。所以这次我就想换个熟一点的技术栈。
我先用 React Native 或 Expo 来试试,想着可以复用以前做网页的经验,还能套用现成的 UI 模板。播放界面做起来挺顺利的,网上有很多开源项目和教学视频。
我选了 Gionatha Sturba 做的一个模板项目(https://github.com/CodeWithGionatha-Labs/music-player),它几乎具备我需要的所有功能。
我本来想通过现成的工具处理文件访问和 iCloud 同步,但很快就遇到了大问题。像 expo-filesystem 这样(https://docs.expo.dev/versions/latest/sdk/filesystem/)的库,虽然可以用来选文件,但要递归扫描 iCloud 里层级很深的文件夹,经常失败,甚至直接把 App 弄崩了。这时候我意识到:JavaScript 的方案反而把事情搞复杂了,还不如直接用 Apple 的原生 API,虽然学起来难度大点,但更靠谱。
iOS 系统的沙盒机制限制很严,App 要访问用户的文件必须获得明确授权。React Native 在这方面很不稳定,想访问 iCloud 里的文件夹不太现实。于是我决定转向 Swift 开发,这样对文件访问和权限控制能掌握得更细致。
转向 SwiftUI
我选了 SwiftUI 而不是 UIKit 或 storyboard,因为它的语法更现代、声明式风格更清爽,不会让 UI 代码干扰到我主要关注的逻辑处理和数据同步。Swift 的 async/await 和 actor 模型也很好用,让我在处理并发和数据流时省了不少力。SwiftUI 还能把 App 分成更清晰的 ViewModel 结构,这对我用 LLM(比如 OpenAI o1 或 DeepSeek)写 UI 代码也有帮助——模型可以直接输出干净的界面或绑定代码,不会出现各种乱七八糟的依赖。
应用架构与数据模型
整个 App 的架构我参考了写后端服务的方式来做:用 SQLite 存储数据,设计成一个简单但清晰的逻辑系统。我没有用 Apple 的 CoreData,因为我需要更高的自由度,比如自己定义数据库结构、写原生 SQL、做全文搜索等等。而 SQLite 原生支持 FTS5(全文搜索引擎),让我能非常高效地做模糊查找,不用再额外集成 Elasticsearch 或自己造轮子。
三个主要界面
这个 App 一共分三个核心页面:
导入音乐库:用户选择 iCloud 文件夹后,App 会扫描所有子目录,找出音频文件,并把它们的路径存到 SQLite 数据库中。这样你就可以自由地搜索、添加文件夹和子文件夹了。Apple 自带的文件选择器非常不好用,不能一次性选中多个目录或按关键词筛选一批文件,这就是它的硬伤。
音乐管理界面:这里可以浏览和管理已导入的歌曲,整理播放列表。我大致照搬了 Apple Music 的操作逻辑,对我来说已经够用了。
播放器:负责播放、暂停、切歌、重复、随机播放、排队等功能。
一个简单的用户使用流程图如下:
第一次打开 App 时,如果还没有导入音乐,会先进入 “同步” 页面,中间有个很大的「添加 iCloud 文件夹」按钮;
选好一个文件夹后,App 会开始扫描文件,进度条会显示处理进度;
扫描完后,会自动跳转到 “音乐库” 页面,展示播放列表 / 艺人 / 专辑 / 歌曲;
点进任意一项,播放条会出现在底部;点播放条可以展开全屏播放器,里面有随机播放、重复、队列排序、音量控制等功能;
你可以随时返回音乐库,音乐继续播放不受影响;
想添加更多音乐,只需返回同步页,点右上角的「+」,再选新的文件夹,系统会在后台自动合并进当前音乐库,无需重启。
像做后端一样设计逻辑层
我之前写后端服务比较多,干脆把 App 的逻辑层也按后端思路来做。整个领域/逻辑层(处理同步、搜索、队列等)完全跟 UI 分离,数据存取也用 SQLite 操作得很精细。
简单说下架构是这样分层的:
最底层是 SQLite,存原始歌曲数据和全文搜索索引;
上面一层是 Repository,封装数据库访问逻辑,提供异步 API;
然后是 Domain Actor(Swift actor),负责业务逻辑,比如导入、搜索、排队等;
ViewModel 再订阅这些 Actor,把数据转换成适合 UI 展示的格式;
最上层的 SwiftUI 只负责“展示”数据,所有状态和逻辑处理都已经在底层搞定,彼此之间不会耦合。
这样一来,iCloud 同步、播放功能和界面展示都能分工明确、互不干扰。
在 SQLite 中实现全文搜索
我前面提到,iOS 从大概 iOS 11 开始,就原生集成了带 FTS 功能的 SQLite。这太好了,我可以不依赖第三方搜索引擎,就实现模糊搜索。
我用 SQLite.swift 这个库来写一般的数据库查询(它有点类似于安全型 SQL 构造器),但 FTS 搜索还是得用原生 SQL 语句来写。
SQLite 的 FTS5 功能对我来说非常关键,它能快速搜索歌曲名、艺人、专辑这些字段,而且不需要额外的索引系统。
创建全文搜索索引表
我建了两个 FTS 表:一个用于索引歌曲(艺术家/标题/专辑),另一个用于文件夹导入期间的文件路径。两个表都放在普通的 B-tree 表(songs、source_paths)旁边。FTS 表在 UI 层是只读的,所有写入都通过 Repository 完成,保证不会漏掉任何数据。
创建搜索索引
一个简单的建表语句如下:
try db.execute("""CREATE VIRTUAL TABLE IF NOT EXISTS songs_fts USING fts5( songId UNINDEXED, artist, title, album, albumArtist, tokenize='unicode61');""")
这里用了 unicode61 分词器,可以支持更多不同语言和字符类型。而像 songId 这样的字段我标记为 UNINDEXED,防止它们占用太多索引空间。
数据可靠更新
为了保证简单又安全,我把所有的更新和插入操作都包裹在事务中。这样一来,即便应用崩溃或中断,搜索索引也不会不同步。
func upsertSong(_ song: Song) async throws { db.transaction { // 插入或更新主歌曲数据 // 插入或更新搜索索引数据 }}
模糊搜索查询
为了让搜索体验更友好,我自动添加了通配符支持。比如你输入“lumine”,系统内部会搜索“lumine*”,即便是部分匹配也能立刻返回结果。
我还利用了 SQLite 内置的智能排序算法(bm25),能在不增加额外复杂度的前提下返回更相关的结果:
SELECT s.*FROM songs s JOIN songs_fts fts ON s.id = fts.songIdWHERE songs_fts MATCH ?ORDER BY bm25(songs_fts)LIMIT ? OFFSET ?;
总的来说,使用原生 SQLite 提供了我所需的灵活性:可预期的 schema、本地优先的访问方式、强大的全文搜索功能,而且无需依赖网络或外部服务。这种方式非常适合一个注重隐私、强调离线使用的应用。
与 iOS 文件系统和书签交互
在 iOS 上,应用可以存储对文件位置的持久书签(bookmarks),但所谓的“安全作用域书签”(security-scoped bookmarks),即允许访问沙盒外部文件的权限机制,仅在 macOS 上可用。iOS 应用只能使用普通书签记录路径,之后需通过文档选择器再次请求访问权限,而且这类访问不能悄无声息地持续生效。
为了缓解这个问题,我实现了一种回退机制:将文件复制到应用自身的沙盒目录中。这样可以规避安全作用域书签生命周期脆弱的问题——比如 iOS 重置权限后可能导致访问失败。我选择在后台主动复制文件,只要书签仍然有效,就能确保不会访问到无效音频路径。
这种方式还能提升索引速度。我可以在访问权限仍然有效时一次性遍历整个目录结构,只导入相关音频文件,并可靠地深入嵌套目录。但要在设备重启后仍能稳定播放这些外部音频文件,目前我还没找到解决方案。这也说明,即便对原生开发者来说,iOS 文件访问的这一用例仍然缺乏支持,处理起来也依然复杂。
构建播放功能和用户界面
元数据解析
为了从音频文件中解析元数据,我使用了 Apple 的 AVFoundation 框架,尤其是 AVURLAsset 类,可以用来检查媒体文件的标题、专辑艺术家等元信息。
虽然大部分元数据由原生 SDK 处理,但比如曲目编号等字段仍需手动从 ID3 标签中提取。我通过 GitHub 搜索(https://github.com/TastemakerDesign/Warper/blob/2af8c07ad8422f4dc3a539177d3a76ee8502e632/plugins/flutter_media_metadata/ios/Classes/Id3MetadataRetriever.swift)找到了一些处理边缘情况的代码示例,因为官方文档在这方面覆盖非常有限。
音频播放功能
当音乐库完成索引后,构建一个播放器其实很简单:初始化一个 AVAudioPlayer 实例播放音频即可。为了支持系统控制中心播放功能,我实现了 AVAudioPlayerDelegate 协议,并接入了 Apple 的 MPRemoteCommandCenter,从而可以响应系统级的播放控制事件。
一些反思
不足之处
Xcode 的局限性仍然令人沮丧。SwiftUI 的实时预览确实是进步,但整体开发体验依旧无法与五年前的 Flutter 相提并论——Flutter 拥有紧密的 VSCode 集成、实时模拟器热重载和熟悉的调试工具。
编辑器灵活性差。想要在 Neovim 或 VSCode 中配置 Swift 的 Language Server Protocol(LSP)支持,你还得安装像 xcode-build-server 这样的工具,效果依旧赶不上 web 开发那种轻快的体验。
Apple 的 SDK 有些部分还停留在 Objective-C 时代。比如 Spotlight 文件搜索功能只能通过 NSMetadataQuery 使用,采用 KVO 和字符串键,没有 Swift 友好的封装。加上文档稀缺,学习成本也就更高。
SwiftUI 的声明式 UI 很棒,但调试 iCloud 相关功能仍需手动 mock。因为 SwiftUI 的预览无法模拟涉及 iCloud 权限的完整行为,必须自行模拟云端交互,虽然只是个小问题,但确实麻烦。
优点之处
async/await 真是福音。终于可以像写同步代码一样写并发逻辑,告别烦人的回调地狱。甚至可以在 Actor 里写 I/O 密集的逻辑,像 JavaScript 那样直接调用,非常丝滑。
丰富的原生库支持。在 React Native/Flutter 等生态里你可能会受限于开源绑定质量,但在 iOS 原生开发中你可以更自由地做“严肃一点”的应用。Apple 提供的许多 API 都附带示例代码,入门门槛反而降低了。
SwiftUI 本身就很棒。React 风格的 UI 构建方式让开发效率更高、更容易试验和构思。Apple 采纳它实在是明智之举。
总结:构建应用本应更简单
折腾了 1.5 周之后,我做出了一个完全满足个人需求的软件 —— 一个可以从云端导入音频文件的本地/离线音乐播放器。
但很快你会意识到,如今的开发者很难自由地把自己写的 App 装到设备上长期使用。没有开发者证书,应用只能运行 7 天,之后你必须重新构建。除非你每年向 Apple 支付 99 美元,注册开发者计划。
即便在欧盟《数字市场法》(DMA)生效后,sideloading(侧载)也仍非完全开放。虽然 EU 用户现在可以从第三方网站直接安装 App,但前提是开发者已经加入 Apple 的 $99/年开发者计划,并接受 Apple 的“替代条款”。对于纯粹的个人或爱好者来说,这并未真正解除“7 天使用期”的限制。
这根本说不通。一家声称推动技术创新的公司,反而在人为设置障碍,阻碍开发者自由创作。即便是渐进式 Web 应用(PWA)在 iOS 上也存在明显限制:即使在 iOS 16~18.x 中,PWA 仍运行在 Safari 的沙盒里。它们获得了 WebGL2 和 Web 推送,但仍然缺乏 Web 蓝牙/USB/NFC、后台同步,甚至连超过约 50MB 的稳定存储也不支持。WebGL 还通过 Metal 的中间层运行,实际帧率远低于原生 Metal 应用——对 UI 来说勉强够用,但无法支撑真正的 3A 级 3D 游戏。
现在 AI 已经显著降低了现代软件开发的门槛,让任何人都能快速上手未知技术、构建自己的工具。我们也看到 Web 开发因其开放性吸引了大量非技术背景的创作者,他们无需掌握一堆技术就能实现自己的想法。但在移动开发领域,你还是得遵守一整套人为的规则。即使是你自己为自己做的 App,Apple 仍然握有决定权,限制你运行超过 7 天。
这家公司曾经点燃了独立开发者的梦想,如今却亲手关上了那扇自由的大门。在 AI 让一切变得更简单的时代里,唯有 iOS 开发仍被死死锁住。
📢 2025 全球产品经理大会
2025 年 8 月 15–16 日
北京·威斯汀酒店
2025 全球产品经理大会将汇聚互联网大厂、AI 创业公司、ToB/ToC 实战一线的产品人,围绕产品设计、用户体验、增长运营、智能落地等核心议题,展开 12 大专题分享,洞察趋势、拆解路径、对话未来。
相关问答
有没有能把男人的声音变成女人的声音的软件?
给你推荐两个:1、变声软件中文破解版AVVCS3.0.89(变男变女变男变少随心所欲)2、AmazingSlowDownerV3.0.2_绿色注册版以上任意一个都可以把男声变成女声!给...
如何使用变声器实现女变男声呢?
1、右击桌面任务栏里的小喇叭,点击【录音设备】。2、打开软件前,点击弹出框里的【录制】,将输入设备设置成电脑本地可用的输入设备(操作如下)*防止因驱动冲...1...
高德地图声音怎么变男声?
高德地图设置男声导航的方法步骤操作如下:1.点击进入高德地图,然后点击进入我的2.进入我的后,点击右上角的设置3.进入设置后,点击进入导航设置4.点击...
手机怎么设置女声变男声?
要将手机上的女声变为男声,通常需要使用语音合成技术。以下是具体步骤:找到语音设置:在手机设置中找到“语音和输入法”或类似的选项。打开语音合成:在语音设...
有什么好的变声软件可以推荐一下的,手机上的,谢谢?
变声器app是现在最火的一款手机应用软件了,通过适度的恶搞可以让聊天的气氛更愉快、有趣。变声器软件可以把自己的声音处理好发给好友,可以达到多种声音效果的...
手机通话怎样设置女声变男声音?
手机通话设置女声变男声音的方法如下:打开电话应用。解锁手机,进入主屏幕,找到并点击电话图标,以打开电话应用。进入通话界面。在电话应用中,点击拨号盘图...
手机里哪里可以设置男声和女声?
可以设置的,设置方法如下:1、有些手机自带有变音功能,可通过设置,设置想要变的声音。2、如手机没有自带这种功能的,可下载有关软件进行设置变声,比如:变...
求推荐手机版那个变声器比较好的?
变声器app是现在最火的一款手机应用软件了,通过适度的恶搞可以让聊天的气氛更愉快、有趣。变声器软件可以把自己的声音处理好发给好友,可以达到多种声音效果的...
oppo手机通话声音怎么能变成女人或男人的声音?
首先,点击手机桌面上的“软件商店”,搜索“幻音变声器”。2.点击右侧的“安装”,系统会自动进行下载并完成安装。3.完成后点击“打开”,允许其获取一定的...
番茄畅听如何切换男女的声音?
番茄畅听切换男女声音步骤如下:1打开番茄畅听,找到想要听读的书籍,并点击,进入该书页面。2点击右下角的“开始播放”3在页面中间部分看到默认的“成熟大叔...