{"id":17048334,"url":"https://github.com/HaishinKit/HaishinKit.kt","last_synced_at":"2026-05-27T08:30:19.916Z","repository":{"id":37561366,"uuid":"74187265","full_name":"shogo4405/HaishinKit.kt","owner":"shogo4405","description":"Camera and Microphone streaming library via RTMP for Android.","archived":false,"fork":false,"pushed_at":"2025-02-09T09:38:19.000Z","size":21917,"stargazers_count":162,"open_issues_count":7,"forks_count":47,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-02-15T07:56:23.935Z","etag":null,"topics":["android","camera","rtmp","streaming"],"latest_commit_sha":null,"homepage":"https://docs.haishinkit.com/kt/latest","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shogo4405.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["shogo4405"],"custom":["https://www.paypal.me/shogo4405"]}},"created_at":"2016-11-19T04:38:32.000Z","updated_at":"2025-02-01T13:39:48.000Z","dependencies_parsed_at":"2023-02-12T12:31:18.606Z","dependency_job_id":"4489a7b4-b4a7-4303-bb8c-ee301cab4c3f","html_url":"https://github.com/shogo4405/HaishinKit.kt","commit_stats":{"total_commits":590,"total_committers":5,"mean_commits":118.0,"dds":"0.31355932203389836","last_synced_commit":"a00970d1eb2fe3fc3716dd293cbe0ad4492c36c2"},"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shogo4405%2FHaishinKit.kt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shogo4405%2FHaishinKit.kt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shogo4405%2FHaishinKit.kt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shogo4405%2FHaishinKit.kt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shogo4405","download_url":"https://codeload.github.com/shogo4405/HaishinKit.kt/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240149887,"owners_count":19755756,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","camera","rtmp","streaming"],"created_at":"2024-10-14T09:51:43.069Z","updated_at":"2026-05-27T08:30:19.863Z","avatar_url":"https://github.com/shogo4405.png","language":"Kotlin","funding_links":["https://github.com/sponsors/shogo4405","https://www.paypal.me/shogo4405","https://www.paypal.me/shogo4405/50USD)/1"],"categories":[],"sub_categories":[],"readme":"# HaishinKit for Android, [iOS, macOS and tvOS](https://github.com/shogo4405/HaishinKit.swift).\n[![GitHub license](https://img.shields.io/badge/license-New%20BSD-blue.svg)](https://raw.githubusercontent.com/shogo4405/HaishinKit.kt/master/LICENSE.md)\n[![](https://jitpack.io/v/shogo4405/HaishinKit~kt.svg)](https://jitpack.io/#shogo4405/HaishinKit~kt)\n[![GitHub Sponsor](https://img.shields.io/static/v1?label=Sponsor\u0026message=%E2%9D%A4\u0026logo=GitHub\u0026color=ff69b4)](https://github.com/sponsors/shogo4405)\n\n* Camera and Microphone streaming library via RTMP for Android.\n* [API Documentation](https://docs.haishinkit.com/kt/latest/)\n\n## 💖 Sponsors\nDo you need additional support? Technical support on Issues and Discussions is provided only to contributors and academic researchers of HaishinKit. By becoming a sponsor, we can provide the support you need.\n\nSponsor: [$50 per month](https://github.com/sponsors/shogo4405): Technical support via GitHub Issues/Discussions with priority response.\n\n## 💬 Communication\n* GitHub Issues and Discussions are open spaces for communication among users and are available to everyone as long as [the code of conduct](https://github.com/shogo4405/HaishinKit.swift?tab=coc-ov-file) is followed.\n* Whether someone is a contributor to HaishinKit is mainly determined by their GitHub profile icon. If you are using the default icon, there is a chance your input might be overlooked, so please consider setting a custom one. It could be a picture of your pet, for example. Personally, I like cats.\n* If you want to support e-mail based communication without GitHub.\n  * Consulting fee is [$50](https://www.paypal.me/shogo4405/50USD)/1 incident. I'm able to response a few days.\n\n## 🌏 Related projects\nProject name    |Notes       |License\n----------------|------------|--------------\n[HaishinKit for iOS, macOS and tvOS.](https://github.com/shogo4405/HaishinKit.swift)|Camera and Microphone streaming library via RTMP for Android.|[BSD 3-Clause \"New\" or \"Revised\" License](https://github.com/shogo4405/HaishinKit.swift/blob/master/LICENSE.md)\n[HaishinKit for Flutter.](https://github.com/shogo4405/HaishinKit.dart)|Camera and Microphone streaming library via RTMP for Flutter.|[BSD 3-Clause \"New\" or \"Revised\" License](https://github.com/shogo4405/HaishinKit.dart/blob/master/LICENSE.md)\n\n## 🎨 Features\n### RTMP\n- [x] Authentication\n- [x] Publish\n- [x] Playback\n- [ ] Action Message Format\n  - [x] AMF0\n  - [ ] ~~AMF3~~\n- [ ] ~~SharedObject~~\n- [x] RTMPS\n  - [x] Native (RTMP over SSL/TSL)\n- [ ] [Enhanced RTMP (Working in progress)](https://github.com/shogo4405/HaishinKit.kt/wiki/Supports-Enhanced-RTMP-Status)\n  - [ ] v1\n  - [ ] v2\n- [x] Audio Codecs\n  - [x] AAC\n- [x] Video Codecs\n  - [x] H264, HEVC\n\n### Recording\nNow support local recording. Additionally, you can specify separate videoSettings and audioSettings from the live stream.\n```kt\nval recorder: StreamRecorder by lazy { StreamRecorder(requireContext()) }\nrecorder.videoSettings.profileLevel = VideoCodecProfileLevel.HEVC_MAIN_3_1\nrecorder.attachStream(stream)\nrecorder.startRecording(\n  File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), \"output.mp4\").toString(),\n  MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4\n)\n```\n\n### Filter\n- [Table Of Filters](https://shogo4405.github.io/HaishinKit.kt/haishinkit/com.haishinkit.graphics.effect/index.html)\n\n### Sources\n- [x] Single camera with Camera2 api\n- [x] Multi camera with Camera2 api\n- [x] MediaProjection\n- [x] Microphone with AudioRecord api.\n\n### View rendering\n|-|HkSurfaceView|HkTextureView|\n|:---:|:---:|:---:|\n|Engine|SurfaceView|TextureView|\n|Playback|beta|beta|\n|Publish|✅ Stable|✅ Stable|\n|Note|Recommend Android 7.0+|Recommend Android 5.0-6.0|\n\n### Others\n- [x] Hardware acceleration for H264 video encoding/AAC audio encoding.\n  - [x] Asynchronously processing.\n- [x] Graphics api\n  - [x] ✅ OpenGL\n  - [ ] 🐛 Vulkan\n\n### Settings\n```kt\nstream.audioSettings.bitrate = 32 * 1000\n\nstream.videoSettings.width = 640 // The width resoulution of video output.\nstream.videoSettings.height = 360 // The height resoulution of video output.\nstream.videoSettings.bitrate = 160 * 1000 // The bitRate of video output.\nstream.videoSettings.IFrameInterval = 2 // The key-frmae interval\n```\n\n### Offscreen Rendering.\nThrough off-screen rendering capabilities, it is possible to display any text or bitmap on a video during broadcasting or viewing. This allows for various applications such as watermarking and time display.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"732\" alt=\"\" src=\"https://github.com/shogo4405/HaishinKit.kt/assets/810189/f2e189eb-d98a-41b4-9b4c-0b7d70637675\"\u003e\n\u003c/p\u003e\n\n```kt\nstream.attachVideo(cameraSource)\n\nval text = Text()\ntext.textSize = 60f\ntext.textValue = \"23:44:56\"\ntext.layoutMargins.set(0, 0, 16, 16)\ntext.horizontalAlignment = ScreenObject.HORIZONTAL_ALIGNMENT_RIGHT\ntext.verticalAlignment = ScreenObject.VERTICAL_ALIGNMENT_BOTTOM\nstream.screen.addChild(text)\n\nval image = Image()\nimage.bitmap = BitmapFactory.decodeResource(resources, R.drawable.game_jikkyou)\nimage.verticalAlignment = ScreenObject.VERTICAL_ALIGNMENT_BOTTOM\nimage.frame.set(0, 0, 180, 180)\nstream.screen.addChild(image)\n```\n\n## 🌏 Architecture Overview\n### Publishing Feature\n\u003cp align=\"center\"\u003e\n  \u003cimg width=\"732\" alt=\"\" src=\"https://user-images.githubusercontent.com/810189/164874912-3cdc0dde-2cfb-4c94-9404-eeb2ff6091ac.png\"\u003e\n\u003c/p\u003e\n\n## 🐾 Examples\nExamples project are available for Android.\n- [x] Camera and microphone publish.\n- [x] RTMP Playback  \n```sh\ngit clone https://github.com/shogo4405/HaishinKit.kt.git\ncd HaishinKit.kt\ngit submodule update --init\n\n# Open [Android Studio] -\u003e [Open] ...\n```\n\n## 🔧 Usage\n\n### Gradle dependency\n**JitPack**\n- A common mistake is trying to use implementation 'com.github.shogo4405.**HaishinKit.kt**', which does not work. The correct form is implementation 'com.github.shogo4405.**HaishinKit~kt**'.\n- In older versions, there may be cases where Jetpack is not supported. If it's not available, please give up and use the latest version.\n```\nallprojects {\n  repositories {\n    maven { url 'https://jitpack.io' }\n  }\n}\n\ndependencies {\n  implementation 'com.github.shogo4405.HaishinKit~kt:haishinkit:x.x.x'\n  implementation 'com.github.shogo4405.HaishinKit~kt:compose:x.x.x'\n  implementation 'com.github.shogo4405.HaishinKit~kt:lottie:x.x.x'\n  implementation 'com.github.shogo4405.HaishinKit~kt:vulkan:x.x.x'\n}\n```\n\n### Dependencies\n|-|minSdk|Android|Requirements|Status|Description|\n|:----|:----|:----|:-----|:----|:----|\n|haishinkit|21+|5|Require|Stable|It's the base module for HaishinKit.|\n|compose|21+|5|Optional|Beta|It's support for a composable component for HaishinKit.|\n|lottie|21+|5|Optional|Beta|It's a module for embedding Lottie animations into live streaming video.|\n|vulkan|26+|8|Optional|Technical preview|It's support for the Vulkan graphics engine.|\n\n### Android manifest\n```xml\n\u003cuses-permission android:name=\"android.permission.INTERNET\" /\u003e\n\u003cuses-permission android:name=\"android.permission.CAMERA\" /\u003e\n\u003cuses-permission android:name=\"android.permission.RECORD_AUDIO\" /\u003e\n```\n\n### Prerequisites\n```kt\nActivityCompat.requestPermissions(this,arrayOf(\n    Manifest.permission.CAMERA,\n    Manifest.permission.RECORD_AUDIO\n), 1)\n```\n\n### RTMP Usage\nReal Time Messaging Protocol (RTMP).\n\n```kt\nclass CameraTabFragment : Fragment(), IEventListener {\n    private lateinit var connection: RtmpConnection\n    private lateinit var stream: RtmpStream\n    private lateinit var cameraView: HkGLSurfaceView\n    private lateinit var cameraSource: CameraSource\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        activity?.let {\n            val permissionCheck = ContextCompat.checkSelfPermission(it, Manifest.permission.CAMERA)\n            if (permissionCheck != PackageManager.PERMISSION_GRANTED) {\n                ActivityCompat.requestPermissions(it, arrayOf(Manifest.permission.CAMERA), 1)\n            }\n            if (ContextCompat.checkSelfPermission(\n                    it,\n                    Manifest.permission.RECORD_AUDIO\n                ) != PackageManager.PERMISSION_GRANTED\n            ) {\n                ActivityCompat.requestPermissions(it, arrayOf(Manifest.permission.RECORD_AUDIO), 1)\n            }\n        }\n        connection = RtmpConnection()\n        stream = RtmpStream(connection)\n        stream.attachAudio(AudioRecordSource())\n        cameraSource = CameraSource(requireContext()).apply {\n            open(CameraCharacteristics.LENS_FACING_BACK)\n        }\n        stream.attachVideo(cameraSource)\n        connection.addEventListener(Event.RTMP_STATUS, this)\n    }\n\n    @SuppressLint(\"SetTextI18n\")\n    override fun onCreateView(\n        inflater: LayoutInflater,\n        container: ViewGroup?,\n        savedInstanceState: Bundle?\n    ): View {\n        val v = inflater.inflate(R.layout.fragment_camera, container, false)\n        val button = v.findViewById\u003cButton\u003e(R.id.button)\n        button.setOnClickListener {\n            if (button.text == \"Publish\") {\n                connection.connect(Preference.shared.rtmpURL)\n                button.text = \"Stop\"\n            } else {\n                connection.close()\n                button.text = \"Publish\"\n            }\n        }\n        val switchButton = v.findViewById\u003cButton\u003e(R.id.switch_button)\n        switchButton.setOnClickListener {\n            cameraSource.switchCamera()\n        }\n        cameraView = v.findViewById(R.id.camera)\n        cameraView.attachStream(stream)\n        return v\n    }\n\n    override fun onDestroy() {\n        super.onDestroy()\n        connection.dispose()\n    }\n\n    override fun handleEvent(event: Event) {\n        Log.i(\"$TAG#handleEvent\", event.toString())\n        val data = EventUtils.toMap(event)\n        val code = data[\"code\"].toString()\n        if (code == RtmpConnection.Code.CONNECT_SUCCESS.rawValue) {\n            stream.publish(Preference.shared.streamName)\n        }\n    }\n\n    companion object {\n        fun newInstance(): CameraTabFragment {\n            return CameraTabFragment()\n        }\n\n        private val TAG = CameraTabFragment::class.java.simpleName\n    }\n}\n```\n\n### Filter API (v0.1)\n```\n- [assets]\n  - [shaders]\n    - custom-shader.vert(optional)\n    - custom-shader.frag\n```\n\n```\npackage my.custom.filter\n\nimport com.haishinkit.graphics.filter.VideoEffect\n\nclass Monochrome2VideoEffect(\n    override val name: String = \"custom-shader\"\n) : VideoEffect\n```\n\n```\nstream.videoEffect = Monochrome2VideoEffect()\n```\n\n## 📓 FAQ\n### How can I compile the vulkan module with Android 5 project?\n#### AndroidManifest.xml\n```xml\n\u003cuses-sdk tools:overrideLibrary=\"com.haishinkit.vulkan\" /\u003e\n```\n\n#### MainActivity\n```kotlin\nif (Build.VERSION.SDK_INT \u003e= Build.VERSION_CODES.O) {\n    PixelTransformFactory.registerPixelTransform(VkPixelTransform::class)\n}\n```\n\n### RTMP URL Format\n* rtmp://server-ip-address[:port]/application/[appInstance]/[prefix:[path1[/path2/]]]streamName\n  - [] mark is an Optional.\n  ```\n  rtmpConneciton.connect(\"rtmp://server-ip-address[:port]/application/[appInstance]\")\n  rtmpStream.publish(\"[prefix:[path1[/path2/]]]streamName\")\n  ```\n* rtmp://localhost/live/streamName\n  ```\n  rtmpConneciton.connect(\"rtmp://localhost/live\")\n  rtmpStream.publish(\"streamName\")\n  ```\n\n### Related Project\n* HaishinKit.swift - Camera and Microphone streaming library via RTMP, HLS for iOS, macOS and tvOS.\n  * https://github.com/shogo4405/HaishinKit.swift\n\n## 📜 License\nBSD-3-Clause\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHaishinKit%2FHaishinKit.kt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHaishinKit%2FHaishinKit.kt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHaishinKit%2FHaishinKit.kt/lists"}