Coder Social home page Coder Social logo

Comments (40)

begeekmyfriend avatar begeekmyfriend commented on May 18, 2024 54

这需要我来说明一下建立这个项目的初衷和开发过程,其实我早就想写了,并非针对你的提问,但跟你的问题还有点关系。鉴于语言表达能力所限,还是用中文吧。

Yasea项目之前,其实我对安卓推流实现几乎一无所知,只是公司为了进军移动端直播而委派给我的新任务,由于公司内部的人对此也是一无所知,所以在软硬编码方案选择上犹豫不决,只能一次又一次尝试。最先参考其它sdk用ffmpeg实现了软编码,由于ffmpeg强大的现成资源,没花多少时间鼓捣一阵后能推流了,但后来发现时间长了手机发烫的问题(当然还有体积庞大的问题),于是又开始尝试硬编码方案。

硬编码方案中,你要解决三个问题——编码、封装、协议。第一个最好办,你可以基于MediaCodec提供的API,编程十分简单;第二个没有现成的,但是我在github上有幸发现srs-sea这个优秀项目,它解决了安卓硬编码输出的h.264/AAC裸流封装为FLV;第三个颇费周折,我上哪去找rtmp的库呢?当时还没有非要用纯Java实现的想法,所以我能找啥就用啥。rtmpdump?最有名的开源librtmp,但代码烂,非首选;rtmp服务器里面抠,代码量太大驾驭不了,倒是看中了SRS里面的srs-librtmp作为备选方案,为此我在github上还建立了repo,并且实现了。

本来以为随便测试一下就这样应付过去算了,直到我无意发现了SimpleRtmp,这是个纯Java实现的RTMP,而且三年没更新了。其实当时我完全可以不必理它的,因为我对Java生疏,不想读源码,但是SimpleRtmp的代码规范简洁,以及注释充分,让我心念一动——何不做成Java一条龙呢?**这是一个创新实现,放眼全世界恐怕没有先例。**就是这个念头让我在清明节花了三天时间把代码和RTMP全部熟悉了一遍,直到胸有成竹,接下来一天时间居然被我用纯Java实现了推流,而且测试通过了好多部安卓手机,效果还不错。

我有点兴奋,但当时并没考虑开源,因为优先考虑给公司产品提供方案。不过开会讨论下来,硬编码仍是作为一个备选方案被搁置了,团队以软编码方案优先。当然我理解团队决定,毕竟考虑到安卓兼容性的问题,在产品应用上是有风险的。

本来呢,这样也就算了,我也算尽忠职守了。不过呢,我想想以前花的力气要真白费了怪可惜的,毕竟github上这方面都没有先例,反正公司看了也不当业务首选,何不开源算了。因为代码主要用了srs-sea,我就随意取了一个名字叫yasea。

我是个闷*的家伙,没事爱到网上吹牛逼,比如知乎上有个问题,如何实现一个直播系统之类,一帮专家们在那里说的长篇大论头头是道,但谁也不肯透露他们做的东西具体怎样的,反正都是一堆SDK,我就说了一句我做了一个yasea,然后贴了一张很一般的效果图。我还给SRS作者写信,跟他说我做了一个yasea,然后表示一下感谢之类的屁话。我还在半夜突发奇想半夜上Hackernews说我做了一个yasea,然后洗洗睡了。

结果第二天知乎上有人私信我了,说你的yasea貌似不支持Nginx-RTMP啊。SRS的作者邮箱回复了,说用Java写RTMP很有趣,然后是一堆鼓励的屁话。一个印度人还在github上提issue说能不能实现MP4录制啊,这玩意儿很有价值但太稀缺了之类。

本来嘛,我可以不理他们的,开源项目就让它自身自灭好了。不过我还算有点好高骛远,何不按照他们的意见试试看呢?于是我居然**全部回复并且承诺了这帮家伙,然后继续做下去了。不过我发现他们的问题和意见其实很有价值,比如Nginx-RTMP为啥推不了,不同服务器有哪些交互,为啥有的安卓机器帧率设置不了,有的芯片的编码器对分辨率数值很敏感,为啥推流一定要搞MP4录制还不是FLV的等等。我发现了很多文档上查不到,而且别人也不会告诉我的秘密。**而且,我对市面上的商业产品——比如映客——背后使用了哪些以技术以及为什么这么设计豁然开朗。

这里趁机正式回复一下你的问题吧——**为啥用硬编码?因为先对软编码,长时间推流手机不发烫是真的。**当然有个前提条件,你不能加特效,无论是美颜软件,还是摄像头自身支持美化磨皮,时间一长就烫得不行,怎么优化都没用,手机GPU优化目前还远远不够。映客这方面都没做好还有,**发烫跟帧率、用Java而不是C实现YUV变换都没有关系。**一个不用任何特效的中低端手机,比一个有特效摄像头的高端手机,十分钟内就能感受到温度的差别,而且是摄像头的位置,而不是电池的位置。

至于编码器芯片,我测过高通、联发科、三星和华为四大厂家基本都涵盖了,至于手机品牌就不用累述。但我不保证每个版本我都测过了,我不是土豪,不是所有手机都在手,比如华为最新的Ascend和Mate,据说用了自家编码器(据说还是强抗烫的那种),yasea就没试过。顺便说一下MTK这个屌丝,就是它对分辨率很敏感,必须是32x(UV分量16x,Y就是32x)不然编码有问题,软编码就没有这个限制。

至于固定参数,的确存在你所说的那种,某些编码器profile和level都是写死的,连fps都是写死的,所以很多人问我为啥设置了fps=24实际输出帧率还这么低,播放不平滑之类。这方面我真的无能为力,因为设备厂商没有标准化,他们就没有强制义务来支持安卓API这种东西——当然谷歌的亲儿子Nexus是支持的。

这些都是基于相当的、规模的、日积月累的对比测试与人的交流得到的靠谱结论。

说了一大堆,这厮对软硬编码有没有整体的看法呢?那就是,市面上大部分安卓采用软编码是一种保险折衷的,同时也是一种稍显平庸的方案。对于“平庸”的理解,一来大家都这么干,依赖很多第三方库,比如无所不能的ffmpeg,还有各种莫名其妙的美颜,导致很多应用体积庞大,耗电量高(当然我也承认某些方案确实做了很多出色的优化,但远没有出色到令人稀奇的地步,大部分我都能看透是怎么一种手段,用了什么库)。相对而言硬编码是一种本质的、激进的,同时也是充满未知风险的方案。比如iOS你可以毫不犹豫地选择硬编码,因为苹果做得好(但也有发烫问题,原因同上),你几乎没有理由不选,省了很多开发;问题在于前面所述的硬件兼容性(实际上我告诉你最新的Android 6.1安装包都有ABI兼容问题,采用了OpenJDK的缘故,这个你肯定不知道吧,以后那些应用发行商要更加头疼了,一次编译到处运行,狡猾的谷记,呵呵呵呵……),所以这个问题只能走一步看一步,一不小心很可能是死刑。但也正因为如此,yasea选择开源,你可以不敢冒商业上的风险,但在开源上你仍然亦步亦趋,我认为这不值得付出这么多努力,因为背后你所能获得的信息和资源(甚至人脉),要远胜于一个只会在公司里闷头苦干拿工资的闷逼。

**生命在于体验,开源在于创新和冒险。**我也不能免俗,还是用鸡汤的方式作个结尾吧。

from yasea.

rockcarry avatar rockcarry commented on May 18, 2024 8

不错的项目,正在研究
看了下代码,能开源绝对要赞,提点建议:

  1. 用到了的开源代码,最好能保持源项目的目录结构和包名类名
  2. 如果对用到的开源项目做了修改,最好能 push 给上游,争取上游能合并自己的改动
    这样开源才能越做越好。

from yasea.

g123x avatar g123x commented on May 18, 2024 1

great job!!!!!!!!!!!!!!!

from yasea.

ygl-rg avatar ygl-rg commented on May 18, 2024

继续努力

from yasea.

zhengxiaochuan-3 avatar zhengxiaochuan-3 commented on May 18, 2024

感谢作者分享精彩心路历程 。持续关注 yasea 。

from yasea.

leepood avatar leepood commented on May 18, 2024

Great Job!

from yasea.

joostshao avatar joostshao commented on May 18, 2024

那些大厂也是心机婊,亏的是我们这些开发者,人家没有义务来帮你做每一个需求,有些还很强硬

from yasea.

crazyhl avatar crazyhl commented on May 18, 2024

感谢分享,努力学习

from yasea.

lisnstatic avatar lisnstatic commented on May 18, 2024

感谢作者为开源做出的贡献。yasea加油!

from yasea.

zjbpku avatar zjbpku commented on May 18, 2024

Very Good.

from yasea.

banketree avatar banketree commented on May 18, 2024

Thinks

from yasea.

hp-xiaomage avatar hp-xiaomage commented on May 18, 2024

非常感谢!

from yasea.

hp-xiaomage avatar hp-xiaomage commented on May 18, 2024

佩服

from yasea.

smartdu avatar smartdu commented on May 18, 2024

请问yasea支持app后台推流、实时切换分辨率么?

from yasea.

lisnstatic avatar lisnstatic commented on May 18, 2024

建了yasea的群,群号:314547660。小问题我们可以在群里讨论,希望作者也可以加进来哈~!

from yasea.

ChadCSong avatar ChadCSong commented on May 18, 2024

谢谢分享,加油

from yasea.

guohai avatar guohai commented on May 18, 2024

楼主有没有碰到过
dequeueOutputBuffer
在部分机器上频繁上报
INFO_TRY_AGAIN_LATER?

from yasea.

begeekmyfriend avatar begeekmyfriend commented on May 18, 2024

@guohai 你把传给编码器的presentationTimeUs改成墙上时间试试。

from yasea.

gouravd avatar gouravd commented on May 18, 2024

@begeekmyfriend can you write down your answer in English :) ?

from yasea.

begeekmyfriend avatar begeekmyfriend commented on May 18, 2024

@gouravd It is the story about why and how I made yasea, difficult for me in English expression :P

from yasea.

lynx-liu avatar lynx-liu commented on May 18, 2024

MTK平台的Gallery2项目中有一个MediaCodecRecorder.java, 其中有用到MediaMuxer把音频和视频数据保存到文件, 即mMediaMuxer.writeSampleData(trackInfo.index, encodedData, bufferInfo);我想把这里的encodedData的视频数据推到服务器, 偿试了flvMuxer.writeSampleData(videoFlvTrack, encodedData, bufferInfo);可是数据并没有传到服务器, 我断点看了一下, 第次if (avc.is_sps(frame))和if (avc.is_pps(frame))都是不成立的, 所以没办法上传服务器, 请教一下,我要如何修改才能实现这个功能?

from yasea.

begeekmyfriend avatar begeekmyfriend commented on May 18, 2024

@llxxhm please open a new issue

from yasea.

lynx-liu avatar lynx-liu commented on May 18, 2024

@begeekmyfriend 已经新建了issue: #47, 其实我的诉求和#10 是一样的

from yasea.

kaedea avatar kaedea commented on May 18, 2024

ProfileLevel固定是BaseLine是因为Native写死了,不过可以通过调用隐藏API解决,问题是无法设置ReferenceFrame…

from yasea.

begeekmyfriend avatar begeekmyfriend commented on May 18, 2024

Now there is soft encoding with x264 in yasea!

from yasea.

kaedea avatar kaedea commented on May 18, 2024

good

from yasea.

JackzrLiu avatar JackzrLiu commented on May 18, 2024

谢谢

from yasea.

blueseaandsky avatar blueseaandsky commented on May 18, 2024

楼主威武!!

from yasea.

hu-ping avatar hu-ping commented on May 18, 2024

楼主威武!!我就是基于你的项目做得美颜功能。非常感谢。

from yasea.

damnboy avatar damnboy commented on May 18, 2024

将屏幕截图用MediaCodec进行编码的时候,同样遇到你说的这种问题。
第一个就是profile的问题。说是编码器内部写死baseline,找了不少资料,发现也有不少人提过这个问题。
但是在红米1上的测试结果。默认profile类型为high。
需要手工修改为baseline。
并且在红米1和魅族mx5上测试编码结果,完全无法实现流畅。
nexus5的效果确实出奇的好,魅族u10也是。
哎,说到底这定制过的系统在加上硬件不兼容带来的问题真是蛋疼的一b。

from yasea.

chenpeimin avatar chenpeimin commented on May 18, 2024

谢谢您的分享!
(1)我看项目有个CPP,此项目是有用到C++吗?
(2)与传统C++对比,效率如何呢?

from yasea.

yannanzheng avatar yannanzheng commented on May 18, 2024

非常感谢您的无私分享!我们也是在进行硬编码时碰到难以解决的兼容性问题打算使用软编码。但是用ffmpeg和x264编译Android平台so文件的时候碰到很多问题,没能成功编译。您可以分享一下相关经验吗?

from yasea.

yiyunchong avatar yiyunchong commented on May 18, 2024

楼主 请问一下publishType值设置为record或者append 服务端能直接录制吗 我用的fms4.5 是无法录制的

from yasea.

imalimin avatar imalimin commented on May 18, 2024

@kaedea 大佬,"ProfileLevel固定是BaseLine是因为Native写死了,不过可以通过调用隐藏API解决",请问这个隐藏api是什么,感谢

from yasea.

begeekmyfriend avatar begeekmyfriend commented on May 18, 2024

@lmylr 如果设备硬件不支持,你改了也白搭

from yasea.

imalimin avatar imalimin commented on May 18, 2024

@begeekmyfriend 这个没事,只要让部分硬件支持的设备能规避系统的限制就可以了,楼主知道那个隐藏api吗?

from yasea.

krmao avatar krmao commented on May 18, 2024

注意到已经支持软编码, 是不是意味着没有特别需要注意的地方,可以商用了?

from yasea.

begeekmyfriend avatar begeekmyfriend commented on May 18, 2024

本项目为免费开源,商用得失概不负责。

from yasea.

krmao avatar krmao commented on May 18, 2024

好的,谢谢分享,加油

from yasea.

gxg-886 avatar gxg-886 commented on May 18, 2024

哪位朋友能帮忙解惑:
1、MediaCodec 就是硬编码吗?
2、我看 yasea 支持硬编和软编的切换,是说 MediaCodec 也可以配置硬编和软编吗?

from yasea.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.