mirror of
https://github.com/HaishinKit/HaishinKit.swift.git
synced 2026-06-06 20:17:36 +00:00
737 lines
40 KiB
HTML
737 lines
40 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<title>HaishinKit Reference</title>
|
||
<link rel="stylesheet" type="text/css" href="css/jazzy.css" />
|
||
<link rel="stylesheet" type="text/css" href="css/highlight.css" />
|
||
<meta charset='utf-8'>
|
||
<script src="js/jquery.min.js" defer></script>
|
||
<script src="js/jazzy.js" defer></script>
|
||
|
||
<script src="js/lunr.min.js" defer></script>
|
||
<script src="js/typeahead.jquery.js" defer></script>
|
||
<script src="js/jazzy.search.js" defer></script>
|
||
</head>
|
||
<body>
|
||
<a title="HaishinKit Reference"></a>
|
||
<header>
|
||
<div class="content-wrapper">
|
||
<p><a href="index.html">HaishinKit 1.3.0 Docs</a> (79% documented)</p>
|
||
<div class="header-right">
|
||
<form role="search" action="search.json">
|
||
<input type="text" placeholder="Search documentation" data-typeahead>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
<div class="content-wrapper">
|
||
<p id="breadcrumbs">
|
||
<a href="index.html">HaishinKit Reference</a>
|
||
<img id="carat" src="img/carat.png" alt=""/>
|
||
HaishinKit Reference
|
||
</p>
|
||
</div>
|
||
<div class="content-wrapper">
|
||
<nav class="sidebar">
|
||
<ul class="nav-groups">
|
||
<li class="nav-group-name">
|
||
<a href="Classes.html">Classes</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AVMixer.html">AVMixer</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AVMixer/Option.html">– Option</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AVMixer/Option.html">– Option</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AVRecorder.html">AVRecorder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AVRecorder/Error.html">– Error</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AudioCodec.html">AudioCodec</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AudioCodec/Option.html">– Option</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AudioCodec/Format.html">– Format</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/AudioEffect.html">AudioEffect</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/ByteArray.html">ByteArray</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/ByteArray/Error.html">– Error</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/Event.html">Event</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/Event/Name.html">– Name</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/EventDispatcher.html">EventDispatcher</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/FLVReader.html">FLVReader</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/HKView.html">HKView</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/HLSService.html">HLSService</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/HTTPService.html">HTTPService</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/HTTPStream.html">HTTPStream</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/MTHKView.html">MTHKView</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/NetClient.html">NetClient</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/NetService.html">NetService</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/NetSocket.html">NetSocket</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/NetStream.html">NetStream</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/PiPHKView.html">PiPHKView</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/PiPHKView.html">PiPHKView</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RTMPConnection.html">RTMPConnection</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RTMPConnection/Code.html">– Code</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RTMPSharedObject.html">RTMPSharedObject</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RTMPStream.html">RTMPStream</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RTMPStream/Code.html">– Code</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RTMPStream/PlayTransition.html">– PlayTransition</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RTMPStream/PlayOption.html">– PlayOption</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/RTMPStream/HowToPublish.html">– HowToPublish</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/Responder.html">Responder</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/ScreenCaptureSession.html">ScreenCaptureSession</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/Setting.html">Setting</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/TSWriter.html">TSWriter</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/VideoCodec.html">VideoCodec</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/VideoCodec/Error.html">– Error</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/VideoCodec/Option.html">– Option</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Classes/VideoEffect.html">VideoEffect</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Global%20Variables.html">Global Variables</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Global%20Variables.html#/s:10HaishinKit12kASUndefinedAA0C0Vvp">kASUndefined</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Enums.html">Enumerations</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Enums/DeviceUtil.html">DeviceUtil</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVAACPacketType.html">FLVAACPacketType</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVAVCPacketType.html">FLVAVCPacketType</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVAudioCodec.html">FLVAudioCodec</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVFrameType.html">FLVFrameType</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVSoundRate.html">FLVSoundRate</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVSoundSize.html">FLVSoundSize</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVSoundType.html">FLVSoundType</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVTagType.html">FLVTagType</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/FLVVideoCodec.html">FLVVideoCodec</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/RTMPObjectEncoding.html">RTMPObjectEncoding</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Enums/ScalingMode.html">ScalingMode</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Extensions.html">Extensions</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Extensions/AVMixer.html">AVMixer</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Extensions/AudioStreamBasicDescription.html">AudioStreamBasicDescription</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Protocols.html">Protocols</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/AVRecorderDelegate.html">AVRecorderDelegate</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/AudioCodecDelegate.html">AudioCodecDelegate</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/CaptureSessionConvertible.html">CaptureSessionConvertible</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/CaptureSessionDelegate.html">CaptureSessionDelegate</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/EventDispatcherConvertible.html">EventDispatcherConvertible</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/FLVTag.html">FLVTag</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/KeyPathRepresentable.html">KeyPathRepresentable</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/NetStreamDrawable.html">NetStreamDrawable</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/RTMPStreamDelegate.html">RTMPStreamDelegate</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/Running.html">Running</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/TSWriterDelegate.html">TSWriterDelegate</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Protocols/VideoCodecDelegate.html">VideoCodecDelegate</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Structs.html">Structures</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Structs/ASArray.html">ASArray</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/ASTypedObject.html">ASTypedObject</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/ASUndefined.html">ASUndefined</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/ASXML.html">ASXML</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/ASXMLDocument.html">ASXMLDocument</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/Atomic.html">Atomic</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/FLVAudioTag.html">FLVAudioTag</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/FLVDataTag.html">FLVDataTag</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/FLVVideoTag.html">FLVVideoTag</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/HTTPRequest.html">HTTPRequest</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/HTTPResponse.html">HTTPResponse</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/RTMPStreamInfo.html">RTMPStreamInfo</a>
|
||
</li>
|
||
<li class="nav-group-task">
|
||
<a href="Structs/SoundTransform.html">SoundTransform</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li class="nav-group-name">
|
||
<a href="Typealiases.html">Type Aliases</a>
|
||
<ul class="nav-group-tasks">
|
||
<li class="nav-group-task">
|
||
<a href="Typealiases.html#/s:10HaishinKit8ASObjecta">ASObject</a>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</nav>
|
||
<article class="main-content">
|
||
<section>
|
||
<section class="section">
|
||
|
||
<h1 id='haishinkit-for-ios-macos-tvos-and-a-href-https-github-com-shogo4405-haishinkit-kt-android-a' class='heading'>HaishinKit for iOS, macOS, tvOS, and <a href="https://github.com/shogo4405/HaishinKit.kt">Android</a>.</h1>
|
||
|
||
<p><a href="http://cocoapods.org/pods/HaishinKit"><img src="https://img.shields.io/cocoapods/p/HaishinKit.svg?style=flat" alt="Platform"></a>
|
||
<img src="https://img.shields.io/badge/language-Swift%205.3-orange.svg" alt="Language">
|
||
<a href="http://cocoapods.org/pods/HaishinKit"><img src="https://img.shields.io/cocoapods/v/HaishinKit.svg?style=flat" alt="CocoaPods"></a>
|
||
<a href="https://raw.githubusercontent.com/shogo4405/HaishinKit.swift/master/LICENSE.md"><img src="https://img.shields.io/badge/License-BSD%203--Clause-blue.svg" alt="GitHub license"></a></p>
|
||
|
||
<ul>
|
||
<li>Camera and Microphone streaming library via RTMP, HLS for iOS, macOS, tvOS.</li>
|
||
<li><a href="https://shogo4405.github.io/HaishinKit.swift/">API Documentation</a></li>
|
||
</ul>
|
||
|
||
<p align="center">
|
||
<strong>Sponsored with 💖 by</strong><br />
|
||
<a href="https://getstream.io/chat/sdk/ios/?utm_source=https://github.com/shogo4405/HaishinKit.swift&utm_medium=github&utm_content=developer&utm_term=swift" target="_blank">
|
||
<img src="https://stream-blog-v2.imgix.net/blog/wp-content/uploads/f7401112f41742c4e173c30d4f318cb8/stream_logo_white.png?w=350" alt="Stream Chat" style="margin: 8px" />
|
||
</a>
|
||
<br />
|
||
Enterprise Grade APIs for Feeds & Chat. <a href="https://getstream.io/tutorials/ios-chat/?utm_source=github.com/shogo4405/HaishinKit.swift&utm_medium=github&utm_campaign=oss_sponsorship" target="_blank">Try the iOS Chat tutorial</a> 💬
|
||
</p>
|
||
<h2 id='communication' class='heading'>💬 Communication</h2>
|
||
|
||
<ul>
|
||
<li>If you need help with making LiveStreaming requests using HaishinKit, use a <a href="https://github.com/shogo4405/HaishinKit.swift/discussions">GitHub Discussions</a> with <strong>Q&A</strong>.</li>
|
||
<li>If you’d like to discuss a feature request, use a <a href="https://github.com/shogo4405/HaishinKit.swift/discussions">GitHub Discussions</a> with <strong>Idea</strong></li>
|
||
<li>If you met a HaishinKit’s bug🐛, use a <a href="https://github.com/shogo4405/HaishinKit.swift/issues">GitHub Issue</a> with <strong>Bug report template</strong>
|
||
|
||
<ul>
|
||
<li>The trace level log is very useful. Please set <code>Logboard.with(HaishinKitIdentifier).level = .trace</code>.</li>
|
||
<li>If you don’t use an issue template. I will immediately close the your issue without a comment.</li>
|
||
</ul></li>
|
||
<li>If you <strong>want to contribute</strong>, submit a pull request!</li>
|
||
<li>If you want to support e-mail based communication without GitHub.
|
||
|
||
<ul>
|
||
<li>Consulting fee is <a href="https://www.paypal.me/shogo4405/50USD">$50</a>/1 incident. I’m able to response a few days.</li>
|
||
</ul></li>
|
||
<li><a href="https://discord.com/invite/8nkshPnanr">Discord chatroom</a>.</li>
|
||
<li>日本語が分かる方は日本語でお願いします!</li>
|
||
</ul>
|
||
<h2 id='sponsors' class='heading'>💖 Sponsors</h2>
|
||
|
||
<p align="center">
|
||
<a href="https://streamlabs.com/" target="_blank"><img src="https://user-images.githubusercontent.com/810189/158178478-cd0484eb-76cf-4e4a-92ef-be5e6228769e.png" width="350px" alt="Streamlabs" /></a>
|
||
</p>
|
||
<h2 id='features' class='heading'>🎨 Features</h2>
|
||
<h3 id='rtmp' class='heading'>RTMP</h3>
|
||
|
||
<ul>
|
||
<li>[x] Authentication</li>
|
||
<li>[x] Publish and Recording (H264/AAC)</li>
|
||
<li>[x] <em>Playback (Beta)</em></li>
|
||
<li>[x] Adaptive bitrate streaming
|
||
|
||
<ul>
|
||
<li>[x] Handling (see also <a href="/../../issues/126">#126</a>)</li>
|
||
<li>[x] Automatic drop frames</li>
|
||
</ul></li>
|
||
<li>[ ] Action Message Format
|
||
|
||
<ul>
|
||
<li>[x] AMF0</li>
|
||
<li>[ ] AMF3</li>
|
||
</ul></li>
|
||
<li>[x] SharedObject</li>
|
||
<li>[x] RTMPS
|
||
|
||
<ul>
|
||
<li>[x] Native (RTMP over SSL/TLS)</li>
|
||
<li>[x] <em>Tunneled (RTMPT over SSL/TLS) (Technical Preview)</em></li>
|
||
</ul></li>
|
||
<li>[x] <em>RTMPT (Technical Preview)</em></li>
|
||
<li>[x] ReplayKit Live as a Broadcast Upload Extension</li>
|
||
</ul>
|
||
<h3 id='hls' class='heading'>HLS</h3>
|
||
|
||
<ul>
|
||
<li>[x] HTTPService</li>
|
||
<li>[x] HLS Publish</li>
|
||
</ul>
|
||
<h3 id='rendering' class='heading'>Rendering</h3>
|
||
|
||
<table><thead>
|
||
<tr>
|
||
<th>-</th>
|
||
<th style="text-align: center"><a href="https://shogo4405.github.io/HaishinKit.swift/Classes/HKView.html">HKView</a></th>
|
||
<th style="text-align: center"><a href="https://shogo4405.github.io/HaishinKit.swift/Classes/PiPHKView.html">PiPHKView</a></th>
|
||
<th style="text-align: center"><a href="https://shogo4405.github.io/HaishinKit.swift/Classes/MTHKView.html">MTHKView</a></th>
|
||
</tr>
|
||
</thead><tbody>
|
||
<tr>
|
||
<td>Engine</td>
|
||
<td style="text-align: center">AVCaptureVideoPreviewLayer</td>
|
||
<td style="text-align: center">AVSampleBufferDisplayLayer</td>
|
||
<td style="text-align: center">Metal</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Publish</td>
|
||
<td style="text-align: center">○</td>
|
||
<td style="text-align: center">◯</td>
|
||
<td style="text-align: center">○</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Playback</td>
|
||
<td style="text-align: center">×</td>
|
||
<td style="text-align: center">◯</td>
|
||
<td style="text-align: center">○</td>
|
||
</tr>
|
||
<tr>
|
||
<td>VisualEffect</td>
|
||
<td style="text-align: center">×</td>
|
||
<td style="text-align: center">◯</td>
|
||
<td style="text-align: center">○</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<h3 id='others' class='heading'>Others</h3>
|
||
|
||
<ul>
|
||
<li>[x] <em>Support tvOS 11.0+ (Technical Preview)</em>
|
||
|
||
<ul>
|
||
<li>tvOS can’t publish Camera and Microphone. Available playback feature.</li>
|
||
</ul></li>
|
||
<li>[x] Hardware acceleration for H264 video encoding, AAC audio encoding</li>
|
||
<li>[x] Support “Allow app extension API only” option</li>
|
||
<li>[ ] <del>Support GPUImage framework (~> 0.5.12)</del>
|
||
|
||
<ul>
|
||
<li><del><a href="https://github.com/shogo4405/GPUHaishinKit.swift/blob/master/README.md">https://github.com/shogo4405/GPUHaishinKit.swift/blob/master/README.md</a></del></li>
|
||
</ul></li>
|
||
<li>[ ] <del>Objective-C Bridging</del></li>
|
||
</ul>
|
||
<h2 id='requirements' class='heading'>🌏 Requirements</h2>
|
||
|
||
<table><thead>
|
||
<tr>
|
||
<th style="text-align: center">-</th>
|
||
<th style="text-align: center">iOS</th>
|
||
<th style="text-align: center">OSX</th>
|
||
<th style="text-align: center">tvOS</th>
|
||
<th style="text-align: center">Xcode</th>
|
||
<th style="text-align: center">Swift</th>
|
||
</tr>
|
||
</thead><tbody>
|
||
<tr>
|
||
<td style="text-align: center">1.3.0+</td>
|
||
<td style="text-align: center">11.0+</td>
|
||
<td style="text-align: center">10.13+</td>
|
||
<td style="text-align: center">10.2+</td>
|
||
<td style="text-align: center">14.0+</td>
|
||
<td style="text-align: center">5.7+</td>
|
||
</tr>
|
||
<tr>
|
||
<td style="text-align: center">1.2.0+</td>
|
||
<td style="text-align: center">9.0+</td>
|
||
<td style="text-align: center">10.11+</td>
|
||
<td style="text-align: center">10.2+</td>
|
||
<td style="text-align: center">13.0+</td>
|
||
<td style="text-align: center">5.5+</td>
|
||
</tr>
|
||
</tbody></table>
|
||
<h2 id='examples' class='heading'>🐾 Examples</h2>
|
||
|
||
<p>Examples project are available for iOS with UIKit, iOS with SwiftUI, macOS and tvOS.</p>
|
||
|
||
<ul>
|
||
<li>[x] Camera and microphone publish.</li>
|
||
<li>[x] RTMP Playback<br>
|
||
<code>sh
|
||
git clone https://github.com/shogo4405/HaishinKit.swift.git
|
||
cd HaishinKit.swift
|
||
carthage bootstrap --use-xcframeworks
|
||
open HaishinKit.xcodeproj
|
||
</code></li>
|
||
</ul>
|
||
<h2 id='cocoa-keys' class='heading'>☕ Cocoa Keys</h2>
|
||
|
||
<p>Please contains Info.plist.</p>
|
||
|
||
<p>iOS 10.0+</p>
|
||
|
||
<ul>
|
||
<li>NSMicrophoneUsageDescription</li>
|
||
<li>NSCameraUsageDescription</li>
|
||
</ul>
|
||
|
||
<p>macOS 10.14+</p>
|
||
|
||
<ul>
|
||
<li>NSMicrophoneUsageDescription</li>
|
||
<li>NSCameraUsageDescription</li>
|
||
</ul>
|
||
<h2 id='installation' class='heading'>🔧 Installation</h2>
|
||
|
||
<p><em>Please set up your project Swift 5.5.</em></p>
|
||
<h3 id='cocoapods' class='heading'>CocoaPods</h3>
|
||
<pre class="highlight ruby"><code><span class="n">source</span> <span class="s1">'https://github.com/CocoaPods/Specs.git'</span>
|
||
<span class="n">use_frameworks!</span>
|
||
|
||
<span class="k">def</span> <span class="nf">import_pods</span>
|
||
<span class="n">pod</span> <span class="s1">'HaishinKit'</span><span class="p">,</span> <span class="s1">'~> 1.2.7
|
||
end
|
||
|
||
target '</span><span class="no">Your</span> <span class="no">Target</span><span class="s1">' do
|
||
platform :ios, '</span><span class="mi">9</span><span class="o">.</span><span class="mi">0</span><span class="err">'</span>
|
||
<span class="n">import_pods</span>
|
||
<span class="k">end</span>
|
||
</code></pre>
|
||
<h3 id='carthage' class='heading'>Carthage</h3>
|
||
<pre class="highlight plaintext"><code>github "shogo4405/HaishinKit.swift" ~> 1.2.7
|
||
</code></pre>
|
||
<h3 id='swift-package-manager' class='heading'>Swift Package Manager</h3>
|
||
<pre class="highlight plaintext"><code>https://github.com/shogo4405/HaishinKit.swift
|
||
</code></pre>
|
||
<h2 id='donation' class='heading'>💠 Donation</h2>
|
||
|
||
<ul>
|
||
<li>GitHub Sponsors
|
||
|
||
<ul>
|
||
<li><a href="https://github.com/sponsors/shogo4405">https://github.com/sponsors/shogo4405</a></li>
|
||
</ul></li>
|
||
<li>Paypal
|
||
|
||
<ul>
|
||
<li><a href="https://www.paypal.me/shogo4405">https://www.paypal.me/shogo4405</a></li>
|
||
</ul></li>
|
||
</ul>
|
||
<h2 id='prerequisites' class='heading'>🔧 Prerequisites</h2>
|
||
|
||
<p>Make sure you setup and activate your AVAudioSession.</p>
|
||
<pre class="highlight swift"><code><span class="kd">import</span> <span class="kt">AVFoundation</span>
|
||
<span class="k">let</span> <span class="nv">session</span> <span class="o">=</span> <span class="kt">AVAudioSession</span><span class="o">.</span><span class="nf">sharedInstance</span><span class="p">()</span>
|
||
<span class="k">do</span> <span class="p">{</span>
|
||
<span class="c1">// https://stackoverflow.com/questions/51010390/avaudiosession-setcategory-swift-4-2-ios-12-play-sound-on-silent</span>
|
||
<span class="k">if</span> <span class="kd">#available(iOS 10.0, *)</span> <span class="p">{</span>
|
||
<span class="k">try</span> <span class="n">session</span><span class="o">.</span><span class="nf">setCategory</span><span class="p">(</span><span class="o">.</span><span class="n">playAndRecord</span><span class="p">,</span> <span class="nv">mode</span><span class="p">:</span> <span class="o">.</span><span class="k">default</span><span class="p">,</span> <span class="nv">options</span><span class="p">:</span> <span class="p">[</span><span class="o">.</span><span class="n">defaultToSpeaker</span><span class="p">,</span> <span class="o">.</span><span class="n">allowBluetooth</span><span class="p">])</span>
|
||
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
|
||
<span class="n">session</span><span class="o">.</span><span class="nf">perform</span><span class="p">(</span><span class="kt">NSSelectorFromString</span><span class="p">(</span><span class="s">"setCategory:withOptions:error:"</span><span class="p">),</span> <span class="nv">with</span><span class="p">:</span> <span class="kt">AVAudioSession</span><span class="o">.</span><span class="kt">Category</span><span class="o">.</span><span class="n">playAndRecord</span><span class="p">,</span> <span class="nv">with</span><span class="p">:</span> <span class="p">[</span>
|
||
<span class="kt">AVAudioSession</span><span class="o">.</span><span class="kt">CategoryOptions</span><span class="o">.</span><span class="n">allowBluetooth</span><span class="p">,</span>
|
||
<span class="kt">AVAudioSession</span><span class="o">.</span><span class="kt">CategoryOptions</span><span class="o">.</span><span class="n">defaultToSpeaker</span><span class="p">]</span>
|
||
<span class="p">)</span>
|
||
<span class="k">try</span> <span class="n">session</span><span class="o">.</span><span class="nf">setMode</span><span class="p">(</span><span class="o">.</span><span class="k">default</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
<span class="k">try</span> <span class="n">session</span><span class="o">.</span><span class="nf">setActive</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
|
||
<span class="p">}</span> <span class="k">catch</span> <span class="p">{</span>
|
||
<span class="nf">print</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
|
||
<span class="p">}</span>
|
||
</code></pre>
|
||
<h2 id='rtmp-usage' class='heading'>📓 RTMP Usage</h2>
|
||
|
||
<p>Real Time Messaging Protocol (RTMP).</p>
|
||
<pre class="highlight swift"><code><span class="k">let</span> <span class="nv">rtmpConnection</span> <span class="o">=</span> <span class="kt">RTMPConnection</span><span class="p">()</span>
|
||
<span class="k">let</span> <span class="nv">rtmpStream</span> <span class="o">=</span> <span class="kt">RTMPStream</span><span class="p">(</span><span class="nv">connection</span><span class="p">:</span> <span class="n">rtmpConnection</span><span class="p">)</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="nf">attachAudio</span><span class="p">(</span><span class="kt">AVCaptureDevice</span><span class="o">.</span><span class="nf">default</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="kt">AVMediaType</span><span class="o">.</span><span class="n">audio</span><span class="p">))</span> <span class="p">{</span> <span class="n">error</span> <span class="k">in</span>
|
||
<span class="c1">// print(error)</span>
|
||
<span class="p">}</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="nf">attachCamera</span><span class="p">(</span><span class="kt">DeviceUtil</span><span class="o">.</span><span class="nf">device</span><span class="p">(</span><span class="nv">withPosition</span><span class="p">:</span> <span class="o">.</span><span class="n">back</span><span class="p">))</span> <span class="p">{</span> <span class="n">error</span> <span class="k">in</span>
|
||
<span class="c1">// print(error)</span>
|
||
<span class="p">}</span>
|
||
|
||
<span class="k">let</span> <span class="nv">hkView</span> <span class="o">=</span> <span class="kt">HKView</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">bounds</span><span class="p">)</span>
|
||
<span class="n">hkView</span><span class="o">.</span><span class="n">videoGravity</span> <span class="o">=</span> <span class="kt">AVLayerVideoGravity</span><span class="o">.</span><span class="n">resizeAspectFill</span>
|
||
<span class="n">hkView</span><span class="o">.</span><span class="nf">attachStream</span><span class="p">(</span><span class="n">rtmpStream</span><span class="p">)</span>
|
||
|
||
<span class="c1">// add ViewController#view</span>
|
||
<span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">hkView</span><span class="p">)</span>
|
||
|
||
<span class="n">rtmpConnection</span><span class="o">.</span><span class="nf">connect</span><span class="p">(</span><span class="s">"rtmp://localhost/appName/instanceName"</span><span class="p">)</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="nf">publish</span><span class="p">(</span><span class="s">"streamName"</span><span class="p">)</span>
|
||
<span class="c1">// if you want to record a stream.</span>
|
||
<span class="c1">// rtmpStream.publish("streamName", type: .localRecord)</span>
|
||
</code></pre>
|
||
<h3 id='rtmp-url-format' class='heading'>RTMP URL Format</h3>
|
||
|
||
<ul>
|
||
<li>rtmp://server-ip-address[:port]/application/[appInstance]/[prefix:[path1[/path2/]]]streamName
|
||
|
||
<ul>
|
||
<li>[] mark is an Optional.
|
||
<code>
|
||
rtmpConneciton.connect("rtmp://server-ip-address[:port]/application/[appInstance]")
|
||
rtmpStream.publish("[prefix:[path1[/path2/]]]streamName")
|
||
</code></li>
|
||
</ul></li>
|
||
<li>rtmp://localhost/live/streamName
|
||
<code>
|
||
rtmpConneciton.connect("rtmp://localhost/live")
|
||
rtmpStream.publish("streamName")
|
||
</code></li>
|
||
</ul>
|
||
<h3 id='settings' class='heading'>Settings</h3>
|
||
<pre class="highlight swift"><code><span class="k">var</span> <span class="nv">rtmpStream</span> <span class="o">=</span> <span class="kt">RTMPStream</span><span class="p">(</span><span class="nv">connection</span><span class="p">:</span> <span class="n">rtmpConnection</span><span class="p">)</span>
|
||
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="n">captureSettings</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="o">.</span><span class="nv">fps</span><span class="p">:</span> <span class="mi">30</span><span class="p">,</span> <span class="c1">// FPS</span>
|
||
<span class="o">.</span><span class="nv">sessionPreset</span><span class="p">:</span> <span class="kt">AVCaptureSession</span><span class="o">.</span><span class="kt">Preset</span><span class="o">.</span><span class="n">medium</span><span class="p">,</span> <span class="c1">// input video width/height</span>
|
||
<span class="c1">// .isVideoMirrored: false,</span>
|
||
<span class="c1">// .continuousAutofocus: false, // use camera autofocus mode</span>
|
||
<span class="c1">// .continuousExposure: false, // use camera exposure mode</span>
|
||
<span class="c1">// .preferredVideoStabilizationMode: AVCaptureVideoStabilizationMode.auto</span>
|
||
<span class="p">]</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="n">audioSettings</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="o">.</span><span class="nv">muted</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="c1">// mute audio</span>
|
||
<span class="o">.</span><span class="nv">bitrate</span><span class="p">:</span> <span class="mi">32</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">,</span>
|
||
<span class="p">]</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="n">videoSettings</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="o">.</span><span class="nv">width</span><span class="p">:</span> <span class="mi">640</span><span class="p">,</span> <span class="c1">// video output width</span>
|
||
<span class="o">.</span><span class="nv">height</span><span class="p">:</span> <span class="mi">360</span><span class="p">,</span> <span class="c1">// video output height</span>
|
||
<span class="o">.</span><span class="nv">bitrate</span><span class="p">:</span> <span class="mi">160</span> <span class="o">*</span> <span class="mi">1000</span><span class="p">,</span> <span class="c1">// video output bitrate</span>
|
||
<span class="o">.</span><span class="nv">profileLevel</span><span class="p">:</span> <span class="n">kVTProfileLevel_H264_Baseline_3_1</span><span class="p">,</span> <span class="c1">// H264 Profile require "import VideoToolbox"</span>
|
||
<span class="o">.</span><span class="nv">maxKeyFrameIntervalDuration</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="c1">// key frame / sec</span>
|
||
<span class="p">]</span>
|
||
<span class="c1">// "0" means the same of input</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="n">recorderSettings</span> <span class="o">=</span> <span class="p">[</span>
|
||
<span class="kt">AVMediaType</span><span class="o">.</span><span class="nv">audio</span><span class="p">:</span> <span class="p">[</span>
|
||
<span class="kt">AVFormatIDKey</span><span class="p">:</span> <span class="kt">Int</span><span class="p">(</span><span class="n">kAudioFormatMPEG4AAC</span><span class="p">),</span>
|
||
<span class="kt">AVSampleRateKey</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
||
<span class="kt">AVNumberOfChannelsKey</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
||
<span class="c1">// AVEncoderBitRateKey: 128000,</span>
|
||
<span class="p">],</span>
|
||
<span class="kt">AVMediaType</span><span class="o">.</span><span class="nv">video</span><span class="p">:</span> <span class="p">[</span>
|
||
<span class="kt">AVVideoCodecKey</span><span class="p">:</span> <span class="kt">AVVideoCodecH264</span><span class="p">,</span>
|
||
<span class="kt">AVVideoHeightKey</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
||
<span class="kt">AVVideoWidthKey</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
||
<span class="cm">/*
|
||
AVVideoCompressionPropertiesKey: [
|
||
AVVideoMaxKeyFrameIntervalDurationKey: 2,
|
||
AVVideoProfileLevelKey: AVVideoProfileLevelH264Baseline30,
|
||
AVVideoAverageBitRateKey: 512000
|
||
]
|
||
*/</span>
|
||
<span class="p">],</span>
|
||
<span class="p">]</span>
|
||
|
||
<span class="c1">// 2nd arguemnt set false</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="nf">attachAudio</span><span class="p">(</span><span class="kt">AVCaptureDevice</span><span class="o">.</span><span class="nf">default</span><span class="p">(</span><span class="nv">for</span><span class="p">:</span> <span class="kt">AVMediaType</span><span class="o">.</span><span class="n">audio</span><span class="p">),</span> <span class="nv">automaticallyConfiguresApplicationAudioSession</span><span class="p">:</span> <span class="kc">false</span><span class="p">)</span>
|
||
|
||
</code></pre>
|
||
<h3 id='authentication' class='heading'>Authentication</h3>
|
||
<pre class="highlight swift"><code><span class="k">var</span> <span class="nv">rtmpConnection</span> <span class="o">=</span> <span class="kt">RTMPConnection</span><span class="p">()</span>
|
||
<span class="n">rtmpConnection</span><span class="o">.</span><span class="nf">connect</span><span class="p">(</span><span class="s">"rtmp://username:password@localhost/appName/instanceName"</span><span class="p">)</span>
|
||
</code></pre>
|
||
<h3 id='screen-capture' class='heading'>Screen Capture</h3>
|
||
<pre class="highlight swift"><code><span class="c1">// iOS</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="nf">attachScreen</span><span class="p">(</span><span class="kt">ScreenCaptureSession</span><span class="p">(</span><span class="nv">shared</span><span class="p">:</span> <span class="kt">UIApplication</span><span class="o">.</span><span class="n">shared</span><span class="p">))</span>
|
||
<span class="c1">// macOS</span>
|
||
<span class="n">rtmpStream</span><span class="o">.</span><span class="nf">attachScreen</span><span class="p">(</span><span class="kt">AVCaptureScreenInput</span><span class="p">(</span><span class="nv">displayID</span><span class="p">:</span> <span class="kt">CGMainDisplayID</span><span class="p">()))</span>
|
||
</code></pre>
|
||
<h2 id='http-usage' class='heading'>📓 HTTP Usage</h2>
|
||
|
||
<p>HTTP Live Streaming (HLS). Your iPhone/Mac become a IP Camera. Basic snipet. You can see <a href="http://ip.address:8080/hello/playlist.m3u8">http://ip.address:8080/hello/playlist.m3u8</a> </p>
|
||
<pre class="highlight swift"><code><span class="k">var</span> <span class="nv">httpStream</span> <span class="o">=</span> <span class="kt">HTTPStream</span><span class="p">()</span>
|
||
<span class="n">httpStream</span><span class="o">.</span><span class="nf">attachCamera</span><span class="p">(</span><span class="kt">DeviceUtil</span><span class="o">.</span><span class="nf">device</span><span class="p">(</span><span class="nv">withPosition</span><span class="p">:</span> <span class="o">.</span><span class="n">back</span><span class="p">))</span>
|
||
<span class="n">httpStream</span><span class="o">.</span><span class="nf">attachAudio</span><span class="p">(</span><span class="kt">AVCaptureDevice</span><span class="o">.</span><span class="nf">defaultDevice</span><span class="p">(</span><span class="nv">withMediaType</span><span class="p">:</span> <span class="kt">AVMediaTypeAudio</span><span class="p">))</span>
|
||
<span class="n">httpStream</span><span class="o">.</span><span class="nf">publish</span><span class="p">(</span><span class="s">"hello"</span><span class="p">)</span>
|
||
|
||
<span class="k">var</span> <span class="nv">hkView</span> <span class="o">=</span> <span class="kt">HKView</span><span class="p">(</span><span class="nv">frame</span><span class="p">:</span> <span class="n">view</span><span class="o">.</span><span class="n">bounds</span><span class="p">)</span>
|
||
<span class="n">hkView</span><span class="o">.</span><span class="nf">attachStream</span><span class="p">(</span><span class="n">httpStream</span><span class="p">)</span>
|
||
|
||
<span class="k">var</span> <span class="nv">httpService</span> <span class="o">=</span> <span class="kt">HLSService</span><span class="p">(</span><span class="nv">domain</span><span class="p">:</span> <span class="s">""</span><span class="p">,</span> <span class="nv">type</span><span class="p">:</span> <span class="s">"_http._tcp"</span><span class="p">,</span> <span class="nv">name</span><span class="p">:</span> <span class="s">"HaishinKit"</span><span class="p">,</span> <span class="nv">port</span><span class="p">:</span> <span class="mi">8080</span><span class="p">)</span>
|
||
<span class="n">httpService</span><span class="o">.</span><span class="nf">startRunning</span><span class="p">()</span>
|
||
<span class="n">httpService</span><span class="o">.</span><span class="nf">addHTTPStream</span><span class="p">(</span><span class="n">httpStream</span><span class="p">)</span>
|
||
|
||
<span class="c1">// add ViewController#view</span>
|
||
<span class="n">view</span><span class="o">.</span><span class="nf">addSubview</span><span class="p">(</span><span class="n">hkView</span><span class="p">)</span>
|
||
</code></pre>
|
||
<h2 id='reference' class='heading'>📖 Reference</h2>
|
||
|
||
<ul>
|
||
<li>Adobe’s Real Time Messaging Protocol
|
||
|
||
<ul>
|
||
<li><a href="http://www.adobe.com/content/dam/Adobe/en/devnet/rtmp/pdf/rtmp_specification_1.0.pdf">http://www.adobe.com/content/dam/Adobe/en/devnet/rtmp/pdf/rtmp_specification_1.0.pdf</a></li>
|
||
</ul></li>
|
||
<li>Action Message Format – AMF 0
|
||
|
||
<ul>
|
||
<li><a href="https://www.adobe.com/content/dam/acom/en/devnet/pdf/amf0-file-format-specification.pdf">https://www.adobe.com/content/dam/acom/en/devnet/pdf/amf0-file-format-specification.pdf</a></li>
|
||
</ul></li>
|
||
<li>Action Message Format – AMF 3
|
||
|
||
<ul>
|
||
<li><a href="https://www.adobe.com/content/dam/acom/en/devnet/pdf/amf-file-format-spec.pdf">https://www.adobe.com/content/dam/acom/en/devnet/pdf/amf-file-format-spec.pdf</a></li>
|
||
</ul></li>
|
||
<li>Video File Format Specification Version 10
|
||
|
||
<ul>
|
||
<li><a href="https://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10.pdf">https://www.adobe.com/content/dam/acom/en/devnet/flv/video_file_format_spec_v10.pdf</a></li>
|
||
</ul></li>
|
||
<li>Adobe Flash Video File Format Specification Version 10.1
|
||
|
||
<ul>
|
||
<li><a href="http://download.macromedia.com/f4v/video_file_format_spec_v10_1.pdf">http://download.macromedia.com/f4v/video_file_format_spec_v10_1.pdf</a></li>
|
||
</ul></li>
|
||
</ul>
|
||
<h2 id='license' class='heading'>📜 License</h2>
|
||
|
||
<p>BSD-3-Clause</p>
|
||
|
||
</section>
|
||
</section>
|
||
<section id="footer">
|
||
<p>© 2022 <a class="link" href="https://github.com/shogo4405/HaishinKit.swift" target="_blank" rel="external noopener">shogo4405</a>. All rights reserved. (Last updated: 2022-09-17)</p>
|
||
<p>Generated by <a class="link" href="https://github.com/realm/jazzy" target="_blank" rel="external noopener">jazzy ♪♫ v0.14.3</a>, a <a class="link" href="https://realm.io" target="_blank" rel="external noopener">Realm</a> project.</p>
|
||
</section>
|
||
</article>
|
||
</div>
|
||
</body>
|
||
</html>
|