@bharper/atv-js 0.2.6 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/dist/index.d.ts +15 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +89 -9
  4. package/dist/index.js.map +1 -1
  5. package/dist/mdns.d.ts.map +1 -1
  6. package/dist/mdns.js +96 -11
  7. package/dist/mdns.js.map +1 -1
  8. package/examples/print-device-json.js +22 -0
  9. package/package.json +2 -3
  10. package/pyatv/.codecov.yml +38 -0
  11. package/pyatv/.github/FUNDING.yml +3 -0
  12. package/pyatv/.github/ISSUE_TEMPLATE/bug_report.yml +80 -0
  13. package/pyatv/.github/ISSUE_TEMPLATE/config.yml +1 -0
  14. package/pyatv/.github/ISSUE_TEMPLATE/feature_request.yml +22 -0
  15. package/pyatv/.github/ISSUE_TEMPLATE/implementation-proposal.yml +29 -0
  16. package/pyatv/.github/ISSUE_TEMPLATE/investigation.yml +16 -0
  17. package/pyatv/.github/ISSUE_TEMPLATE/minor-change.yml +10 -0
  18. package/pyatv/.github/ISSUE_TEMPLATE/question-or-idea.yml +11 -0
  19. package/pyatv/.github/dependabot.yml +26 -0
  20. package/pyatv/.github/workflows/codeql-analysis.yml +71 -0
  21. package/pyatv/.github/workflows/release.yml +160 -0
  22. package/pyatv/.github/workflows/tests.yml +104 -0
  23. package/pyatv/.gitpod.yml +23 -0
  24. package/pyatv/CHANGES.md +3708 -0
  25. package/pyatv/CODE_OF_CONDUCT.md +76 -0
  26. package/pyatv/CONTRIBUTING.md +72 -0
  27. package/pyatv/CONTRIBUTORS.md +3 -0
  28. package/pyatv/Dockerfile +15 -0
  29. package/pyatv/LICENSE.md +9 -0
  30. package/pyatv/MANIFEST.in +14 -0
  31. package/pyatv/README.md +111 -0
  32. package/pyatv/base_versions.txt +13 -0
  33. package/pyatv/chickn.yaml +75 -0
  34. package/pyatv/docs/404.html +24 -0
  35. package/pyatv/docs/CNAME +1 -0
  36. package/pyatv/docs/Gemfile +31 -0
  37. package/pyatv/docs/_config.yml +121 -0
  38. package/pyatv/docs/_includes/api +10 -0
  39. package/pyatv/docs/_includes/atvremote_scan +32 -0
  40. package/pyatv/docs/_includes/code +6 -0
  41. package/pyatv/docs/_includes/issue +14 -0
  42. package/pyatv/docs/_includes/pypi +5 -0
  43. package/pyatv/docs/_layouts/template.html +109 -0
  44. package/pyatv/docs/api/pyatv.conf.html +312 -0
  45. package/pyatv/docs/api/pyatv.const.html +974 -0
  46. package/pyatv/docs/api/pyatv.convert.html +106 -0
  47. package/pyatv/docs/api/pyatv.exceptions.html +489 -0
  48. package/pyatv/docs/api/pyatv.helpers.html +102 -0
  49. package/pyatv/docs/api/pyatv.html +120 -0
  50. package/pyatv/docs/api/pyatv.interface.html +2369 -0
  51. package/pyatv/docs/api/pyatv.settings.html +484 -0
  52. package/pyatv/docs/api/pyatv.storage.file_storage.html +102 -0
  53. package/pyatv/docs/api/pyatv.storage.html +186 -0
  54. package/pyatv/docs/api/pyatv.storage.memory_storage.html +83 -0
  55. package/pyatv/docs/assets/css/custom.css +19 -0
  56. package/pyatv/docs/assets/css/hljs.css +1 -0
  57. package/pyatv/docs/assets/css/normalize.css +349 -0
  58. package/pyatv/docs/assets/css/pdoc.css +287 -0
  59. package/pyatv/docs/assets/css/sanitize.css +566 -0
  60. package/pyatv/docs/assets/css/style.scss +9 -0
  61. package/pyatv/docs/assets/img/logo.svg +63 -0
  62. package/pyatv/docs/assets/js/highlight.9.12.0.min.js +3 -0
  63. package/pyatv/docs/assets/js/mermaid.8.9.2.min.js +32 -0
  64. package/pyatv/docs/assets/js/mermaid.min.js.map +1 -0
  65. package/pyatv/docs/development/apps.md +81 -0
  66. package/pyatv/docs/development/audio.md +42 -0
  67. package/pyatv/docs/development/control.md +56 -0
  68. package/pyatv/docs/development/development.md +15 -0
  69. package/pyatv/docs/development/device_info.md +36 -0
  70. package/pyatv/docs/development/examples.md +44 -0
  71. package/pyatv/docs/development/features.md +70 -0
  72. package/pyatv/docs/development/keyboard.md +51 -0
  73. package/pyatv/docs/development/listeners.md +144 -0
  74. package/pyatv/docs/development/logging.md +55 -0
  75. package/pyatv/docs/development/metadata.md +115 -0
  76. package/pyatv/docs/development/power_management.md +53 -0
  77. package/pyatv/docs/development/scan_pair_and_connect.md +331 -0
  78. package/pyatv/docs/development/services.md +9 -0
  79. package/pyatv/docs/development/storage.md +259 -0
  80. package/pyatv/docs/development/stream.md +241 -0
  81. package/pyatv/docs/development/testing.md +9 -0
  82. package/pyatv/docs/documentation/atvlog.md +64 -0
  83. package/pyatv/docs/documentation/atvproxy.md +244 -0
  84. package/pyatv/docs/documentation/atvremote.md +639 -0
  85. package/pyatv/docs/documentation/atvscript.md +275 -0
  86. package/pyatv/docs/documentation/concepts.md +168 -0
  87. package/pyatv/docs/documentation/documentation.md +130 -0
  88. package/pyatv/docs/documentation/getting_started.md +248 -0
  89. package/pyatv/docs/documentation/protocols.md +1959 -0
  90. package/pyatv/docs/documentation/supported_features.md +246 -0
  91. package/pyatv/docs/documentation/tutorial.md +1062 -0
  92. package/pyatv/docs/documentation/workspace.code-workspace +7 -0
  93. package/pyatv/docs/favicon.ico +0 -0
  94. package/pyatv/docs/index.md +109 -0
  95. package/pyatv/docs/internals/design.md +354 -0
  96. package/pyatv/docs/internals/documentation.md +84 -0
  97. package/pyatv/docs/internals/interfaces.md +95 -0
  98. package/pyatv/docs/internals/internals.md +157 -0
  99. package/pyatv/docs/internals/submit_pr.md +56 -0
  100. package/pyatv/docs/internals/testing.md +176 -0
  101. package/pyatv/docs/internals/tools.md +574 -0
  102. package/pyatv/docs/pdoc_templates/config.mako +46 -0
  103. package/pyatv/docs/pdoc_templates/html.mako +454 -0
  104. package/pyatv/docs/support/acknowledgements.md +87 -0
  105. package/pyatv/docs/support/faq.md +214 -0
  106. package/pyatv/docs/support/migration.md +138 -0
  107. package/pyatv/docs/support/scanning_issues.md +110 -0
  108. package/pyatv/docs/support/support.md +18 -0
  109. package/pyatv/docs/support/troubleshooting.md +83 -0
  110. package/pyatv/pyatv/protocols/mrp/protobuf/AudioFadeMessage.proto +13 -0
  111. package/pyatv/pyatv/protocols/mrp/protobuf/AudioFadeMessage_pb2.pyi +37 -0
  112. package/pyatv/pyatv/protocols/mrp/protobuf/AudioFadeResponseMessage.proto +11 -0
  113. package/pyatv/pyatv/protocols/mrp/protobuf/AudioFadeResponseMessage_pb2.pyi +32 -0
  114. package/pyatv/pyatv/protocols/mrp/protobuf/AudioFormatSettingsMessage.proto +5 -0
  115. package/pyatv/pyatv/protocols/mrp/protobuf/AudioFormatSettingsMessage_pb2.pyi +27 -0
  116. package/pyatv/pyatv/protocols/mrp/protobuf/ClientUpdatesConfigMessage.proto +16 -0
  117. package/pyatv/pyatv/protocols/mrp/protobuf/ClientUpdatesConfigMessage_pb2.pyi +44 -0
  118. package/pyatv/pyatv/protocols/mrp/protobuf/CommandInfo.proto +117 -0
  119. package/pyatv/pyatv/protocols/mrp/protobuf/CommandInfo_pb2.pyi +325 -0
  120. package/pyatv/pyatv/protocols/mrp/protobuf/CommandOptions.proto +36 -0
  121. package/pyatv/pyatv/protocols/mrp/protobuf/CommandOptions_pb2.pyi +115 -0
  122. package/pyatv/pyatv/protocols/mrp/protobuf/Common.proto +79 -0
  123. package/pyatv/pyatv/protocols/mrp/protobuf/Common_pb2.pyi +228 -0
  124. package/pyatv/pyatv/protocols/mrp/protobuf/ConfigureConnectionMessage.proto +11 -0
  125. package/pyatv/pyatv/protocols/mrp/protobuf/ConfigureConnectionMessage_pb2.pyi +32 -0
  126. package/pyatv/pyatv/protocols/mrp/protobuf/ContentItem.proto +27 -0
  127. package/pyatv/pyatv/protocols/mrp/protobuf/ContentItemMetadata.proto +213 -0
  128. package/pyatv/pyatv/protocols/mrp/protobuf/ContentItemMetadata_pb2.pyi +630 -0
  129. package/pyatv/pyatv/protocols/mrp/protobuf/ContentItem_pb2.pyi +94 -0
  130. package/pyatv/pyatv/protocols/mrp/protobuf/CryptoPairingMessage.proto +15 -0
  131. package/pyatv/pyatv/protocols/mrp/protobuf/CryptoPairingMessage_pb2.pyi +46 -0
  132. package/pyatv/pyatv/protocols/mrp/protobuf/DeviceInfoMessage.proto +69 -0
  133. package/pyatv/pyatv/protocols/mrp/protobuf/DeviceInfoMessage_pb2.pyi +226 -0
  134. package/pyatv/pyatv/protocols/mrp/protobuf/GenericMessage.proto +12 -0
  135. package/pyatv/pyatv/protocols/mrp/protobuf/GenericMessage_pb2.pyi +35 -0
  136. package/pyatv/pyatv/protocols/mrp/protobuf/GetKeyboardSessionMessage.proto +11 -0
  137. package/pyatv/pyatv/protocols/mrp/protobuf/GetKeyboardSessionMessage_pb2.pyi +26 -0
  138. package/pyatv/pyatv/protocols/mrp/protobuf/GetRemoteTextInputSessionMessage.proto +10 -0
  139. package/pyatv/pyatv/protocols/mrp/protobuf/GetRemoteTextInputSessionMessage_pb2.pyi +26 -0
  140. package/pyatv/pyatv/protocols/mrp/protobuf/GetVolumeMessage.proto +11 -0
  141. package/pyatv/pyatv/protocols/mrp/protobuf/GetVolumeMessage_pb2.pyi +32 -0
  142. package/pyatv/pyatv/protocols/mrp/protobuf/GetVolumeResultMessage.proto +11 -0
  143. package/pyatv/pyatv/protocols/mrp/protobuf/GetVolumeResultMessage_pb2.pyi +32 -0
  144. package/pyatv/pyatv/protocols/mrp/protobuf/KeyboardMessage.proto +88 -0
  145. package/pyatv/pyatv/protocols/mrp/protobuf/KeyboardMessage_pb2.pyi +261 -0
  146. package/pyatv/pyatv/protocols/mrp/protobuf/LanguageOption.proto +9 -0
  147. package/pyatv/pyatv/protocols/mrp/protobuf/LanguageOption_pb2.pyi +42 -0
  148. package/pyatv/pyatv/protocols/mrp/protobuf/ModifyOutputContextRequestMessage.proto +23 -0
  149. package/pyatv/pyatv/protocols/mrp/protobuf/ModifyOutputContextRequestMessage_pb2.pyi +86 -0
  150. package/pyatv/pyatv/protocols/mrp/protobuf/NotificationMessage.proto +12 -0
  151. package/pyatv/pyatv/protocols/mrp/protobuf/NotificationMessage_pb2.pyi +38 -0
  152. package/pyatv/pyatv/protocols/mrp/protobuf/NowPlayingClient.proto +12 -0
  153. package/pyatv/pyatv/protocols/mrp/protobuf/NowPlayingClient_pb2.pyi +49 -0
  154. package/pyatv/pyatv/protocols/mrp/protobuf/NowPlayingInfo.proto +24 -0
  155. package/pyatv/pyatv/protocols/mrp/protobuf/NowPlayingInfo_pb2.pyi +79 -0
  156. package/pyatv/pyatv/protocols/mrp/protobuf/NowPlayingPlayer.proto +11 -0
  157. package/pyatv/pyatv/protocols/mrp/protobuf/NowPlayingPlayer_pb2.pyi +45 -0
  158. package/pyatv/pyatv/protocols/mrp/protobuf/Origin.proto +17 -0
  159. package/pyatv/pyatv/protocols/mrp/protobuf/OriginClientPropertiesMessage.proto +11 -0
  160. package/pyatv/pyatv/protocols/mrp/protobuf/OriginClientPropertiesMessage_pb2.pyi +32 -0
  161. package/pyatv/pyatv/protocols/mrp/protobuf/Origin_pb2.pyi +63 -0
  162. package/pyatv/pyatv/protocols/mrp/protobuf/PlaybackQueue.proto +15 -0
  163. package/pyatv/pyatv/protocols/mrp/protobuf/PlaybackQueueCapabilities.proto +7 -0
  164. package/pyatv/pyatv/protocols/mrp/protobuf/PlaybackQueueCapabilities_pb2.pyi +33 -0
  165. package/pyatv/pyatv/protocols/mrp/protobuf/PlaybackQueueContext.proto +5 -0
  166. package/pyatv/pyatv/protocols/mrp/protobuf/PlaybackQueueContext_pb2.pyi +27 -0
  167. package/pyatv/pyatv/protocols/mrp/protobuf/PlaybackQueueRequestMessage.proto +29 -0
  168. package/pyatv/pyatv/protocols/mrp/protobuf/PlaybackQueueRequestMessage_pb2.pyi +87 -0
  169. package/pyatv/pyatv/protocols/mrp/protobuf/PlaybackQueue_pb2.pyi +53 -0
  170. package/pyatv/pyatv/protocols/mrp/protobuf/PlayerClientPropertiesMessage.proto +13 -0
  171. package/pyatv/pyatv/protocols/mrp/protobuf/PlayerClientPropertiesMessage_pb2.pyi +37 -0
  172. package/pyatv/pyatv/protocols/mrp/protobuf/PlayerPath.proto +11 -0
  173. package/pyatv/pyatv/protocols/mrp/protobuf/PlayerPath_pb2.pyi +39 -0
  174. package/pyatv/pyatv/protocols/mrp/protobuf/ProtocolMessage.proto +171 -0
  175. package/pyatv/pyatv/protocols/mrp/protobuf/ProtocolMessage_pb2.pyi +377 -0
  176. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterForGameControllerEventsMessage.proto +18 -0
  177. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterForGameControllerEventsMessage_pb2.pyi +54 -0
  178. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterHIDDeviceMessage.proto +12 -0
  179. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterHIDDeviceMessage_pb2.pyi +34 -0
  180. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterHIDDeviceResultMessage.proto +12 -0
  181. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterHIDDeviceResultMessage_pb2.pyi +35 -0
  182. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterVoiceInputDeviceMessage.proto +12 -0
  183. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterVoiceInputDeviceMessage_pb2.pyi +34 -0
  184. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterVoiceInputDeviceResponseMessage.proto +12 -0
  185. package/pyatv/pyatv/protocols/mrp/protobuf/RegisterVoiceInputDeviceResponseMessage_pb2.pyi +35 -0
  186. package/pyatv/pyatv/protocols/mrp/protobuf/RemoteTextInputMessage.proto +13 -0
  187. package/pyatv/pyatv/protocols/mrp/protobuf/RemoteTextInputMessage_pb2.pyi +38 -0
  188. package/pyatv/pyatv/protocols/mrp/protobuf/RemoveClientMessage.proto +12 -0
  189. package/pyatv/pyatv/protocols/mrp/protobuf/RemoveClientMessage_pb2.pyi +34 -0
  190. package/pyatv/pyatv/protocols/mrp/protobuf/RemoveEndpointsMessage.proto +11 -0
  191. package/pyatv/pyatv/protocols/mrp/protobuf/RemoveEndpointsMessage_pb2.pyi +34 -0
  192. package/pyatv/pyatv/protocols/mrp/protobuf/RemoveOutputDevicesMessage.proto +12 -0
  193. package/pyatv/pyatv/protocols/mrp/protobuf/RemoveOutputDevicesMessage_pb2.pyi +38 -0
  194. package/pyatv/pyatv/protocols/mrp/protobuf/RemovePlayerMessage.proto +12 -0
  195. package/pyatv/pyatv/protocols/mrp/protobuf/RemovePlayerMessage_pb2.pyi +34 -0
  196. package/pyatv/pyatv/protocols/mrp/protobuf/SendButtonEventMessage.proto +13 -0
  197. package/pyatv/pyatv/protocols/mrp/protobuf/SendButtonEventMessage_pb2.pyi +38 -0
  198. package/pyatv/pyatv/protocols/mrp/protobuf/SendCommandMessage.proto +16 -0
  199. package/pyatv/pyatv/protocols/mrp/protobuf/SendCommandMessage_pb2.pyi +43 -0
  200. package/pyatv/pyatv/protocols/mrp/protobuf/SendCommandResultMessage.proto +100 -0
  201. package/pyatv/pyatv/protocols/mrp/protobuf/SendCommandResultMessage_pb2.pyi +286 -0
  202. package/pyatv/pyatv/protocols/mrp/protobuf/SendHIDEventMessage.proto +41 -0
  203. package/pyatv/pyatv/protocols/mrp/protobuf/SendHIDEventMessage_pb2.pyi +63 -0
  204. package/pyatv/pyatv/protocols/mrp/protobuf/SendPackedVirtualTouchEventMessage.proto +24 -0
  205. package/pyatv/pyatv/protocols/mrp/protobuf/SendPackedVirtualTouchEventMessage_pb2.pyi +64 -0
  206. package/pyatv/pyatv/protocols/mrp/protobuf/SendVoiceInputMessage.proto +38 -0
  207. package/pyatv/pyatv/protocols/mrp/protobuf/SendVoiceInputMessage_pb2.pyi +134 -0
  208. package/pyatv/pyatv/protocols/mrp/protobuf/SetArtworkMessage.proto +11 -0
  209. package/pyatv/pyatv/protocols/mrp/protobuf/SetArtworkMessage_pb2.pyi +32 -0
  210. package/pyatv/pyatv/protocols/mrp/protobuf/SetConnectionStateMessage.proto +18 -0
  211. package/pyatv/pyatv/protocols/mrp/protobuf/SetConnectionStateMessage_pb2.pyi +54 -0
  212. package/pyatv/pyatv/protocols/mrp/protobuf/SetDefaultSupportedCommandsMessage.proto +28 -0
  213. package/pyatv/pyatv/protocols/mrp/protobuf/SetDefaultSupportedCommandsMessage_pb2.pyi +74 -0
  214. package/pyatv/pyatv/protocols/mrp/protobuf/SetDiscoveryModeMessage.proto +12 -0
  215. package/pyatv/pyatv/protocols/mrp/protobuf/SetDiscoveryModeMessage_pb2.pyi +35 -0
  216. package/pyatv/pyatv/protocols/mrp/protobuf/SetHiliteModeMessage.proto +11 -0
  217. package/pyatv/pyatv/protocols/mrp/protobuf/SetHiliteModeMessage_pb2.pyi +32 -0
  218. package/pyatv/pyatv/protocols/mrp/protobuf/SetNowPlayingClientMessage.proto +12 -0
  219. package/pyatv/pyatv/protocols/mrp/protobuf/SetNowPlayingClientMessage_pb2.pyi +34 -0
  220. package/pyatv/pyatv/protocols/mrp/protobuf/SetNowPlayingPlayerMessage.proto +12 -0
  221. package/pyatv/pyatv/protocols/mrp/protobuf/SetNowPlayingPlayerMessage_pb2.pyi +34 -0
  222. package/pyatv/pyatv/protocols/mrp/protobuf/SetRecordingStateMessage.proto +17 -0
  223. package/pyatv/pyatv/protocols/mrp/protobuf/SetRecordingStateMessage_pb2.pyi +54 -0
  224. package/pyatv/pyatv/protocols/mrp/protobuf/SetStateMessage.proto +27 -0
  225. package/pyatv/pyatv/protocols/mrp/protobuf/SetStateMessage_pb2.pyi +72 -0
  226. package/pyatv/pyatv/protocols/mrp/protobuf/SetVolumeMessage.proto +12 -0
  227. package/pyatv/pyatv/protocols/mrp/protobuf/SetVolumeMessage_pb2.pyi +35 -0
  228. package/pyatv/pyatv/protocols/mrp/protobuf/SupportedCommands.proto +7 -0
  229. package/pyatv/pyatv/protocols/mrp/protobuf/SupportedCommands_pb2.pyi +30 -0
  230. package/pyatv/pyatv/protocols/mrp/protobuf/TextInputMessage.proto +23 -0
  231. package/pyatv/pyatv/protocols/mrp/protobuf/TextInputMessage_pb2.pyi +76 -0
  232. package/pyatv/pyatv/protocols/mrp/protobuf/TransactionKey.proto +6 -0
  233. package/pyatv/pyatv/protocols/mrp/protobuf/TransactionKey_pb2.pyi +30 -0
  234. package/pyatv/pyatv/protocols/mrp/protobuf/TransactionMessage.proto +15 -0
  235. package/pyatv/pyatv/protocols/mrp/protobuf/TransactionMessage_pb2.pyi +42 -0
  236. package/pyatv/pyatv/protocols/mrp/protobuf/TransactionPacket.proto +11 -0
  237. package/pyatv/pyatv/protocols/mrp/protobuf/TransactionPacket_pb2.pyi +41 -0
  238. package/pyatv/pyatv/protocols/mrp/protobuf/TransactionPackets.proto +7 -0
  239. package/pyatv/pyatv/protocols/mrp/protobuf/TransactionPackets_pb2.pyi +30 -0
  240. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateClientMessage.proto +12 -0
  241. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateClientMessage_pb2.pyi +34 -0
  242. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateContentItemArtworkMessage.proto +14 -0
  243. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateContentItemArtworkMessage_pb2.pyi +41 -0
  244. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateContentItemMessage.proto +14 -0
  245. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateContentItemMessage_pb2.pyi +41 -0
  246. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateEndPointsMessage.proto +25 -0
  247. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateEndPointsMessage_pb2.pyi +74 -0
  248. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateOutputDeviceMessage.proto +88 -0
  249. package/pyatv/pyatv/protocols/mrp/protobuf/UpdateOutputDeviceMessage_pb2.pyi +277 -0
  250. package/pyatv/pyatv/protocols/mrp/protobuf/UpdatePlayerPath.proto +12 -0
  251. package/pyatv/pyatv/protocols/mrp/protobuf/UpdatePlayerPath_pb2.pyi +34 -0
  252. package/pyatv/pyatv/protocols/mrp/protobuf/VirtualTouchDeviceDescriptorMessage.proto +8 -0
  253. package/pyatv/pyatv/protocols/mrp/protobuf/VirtualTouchDeviceDescriptorMessage_pb2.pyi +36 -0
  254. package/pyatv/pyatv/protocols/mrp/protobuf/VoiceInputDeviceDescriptorMessage.proto +8 -0
  255. package/pyatv/pyatv/protocols/mrp/protobuf/VoiceInputDeviceDescriptorMessage_pb2.pyi +35 -0
  256. package/pyatv/pyatv/protocols/mrp/protobuf/VolumeControlAvailabilityMessage.proto +23 -0
  257. package/pyatv/pyatv/protocols/mrp/protobuf/VolumeControlAvailabilityMessage_pb2.pyi +71 -0
  258. package/pyatv/pyatv/protocols/mrp/protobuf/VolumeControlCapabilitiesDidChangeMessage.proto +14 -0
  259. package/pyatv/pyatv/protocols/mrp/protobuf/VolumeControlCapabilitiesDidChangeMessage_pb2.pyi +40 -0
  260. package/pyatv/pyatv/protocols/mrp/protobuf/VolumeDidChangeMessage.proto +13 -0
  261. package/pyatv/pyatv/protocols/mrp/protobuf/VolumeDidChangeMessage_pb2.pyi +38 -0
  262. package/pyatv/pyatv/protocols/mrp/protobuf/WakeDeviceMessage.proto +11 -0
  263. package/pyatv/pyatv/protocols/mrp/protobuf/WakeDeviceMessage_pb2.pyi +26 -0
  264. package/pyatv/pyatv/py.typed +0 -0
  265. package/pyatv/pylintrc +49 -0
  266. package/pyatv/pyproject.toml +74 -0
  267. package/pyatv/requirements/requirements.txt +14 -0
  268. package/pyatv/requirements/requirements_docs.txt +2 -0
  269. package/pyatv/requirements/requirements_test.txt +20 -0
  270. package/pyatv/scripts/build_docs.sh +17 -0
  271. package/pyatv/scripts/setup_dev_env.sh +83 -0
  272. package/pyatv/setup.cfg +14 -0
  273. package/pyatv/tests/data/README +23 -0
  274. package/pyatv/tests/data/audio_10_frames.wav +0 -0
  275. package/pyatv/tests/data/audio_1_packet_metadata.wav +0 -0
  276. package/pyatv/tests/data/audio_3_packets.wav +0 -0
  277. package/pyatv/tests/data/only_metadata.wav +0 -0
  278. package/pyatv/tests/data/only_title.wav +0 -0
  279. package/pyatv/tests/data/static_3sec.ogg +0 -0
  280. package/pyatv/tests/data/testfile.txt +1 -0
  281. package/pyatv/tests/support/pyatv.code-workspace +14 -0
  282. package/src/index.ts +122 -8
  283. package/src/mdns.ts +64 -11
@@ -0,0 +1,115 @@
1
+ ---
2
+ layout: template
3
+ title: Metadata
4
+ permalink: /development/metadata/
5
+ link_group: development
6
+ ---
7
+ # Metadata
8
+
9
+ It is possible to get metadata, i.e. what is playing, using two different
10
+ methods:
11
+
12
+ * Manually polling
13
+ * Push updates
14
+
15
+ Polling metadata from the device works very similar to the remote control
16
+ API, but one asynchronous call will return an object containing all metadata.
17
+ This is to lower the amount of device calls needed. Artwork is retrieved
18
+ separately.
19
+
20
+ When using push updates, new updates are *pushed* from the Apple TV when
21
+ something of interest happens. The exact same data that is available when
22
+ polling, is passed to a callback provided by the API user.
23
+
24
+ Push updates are described further in the [Listeners](../listeners) section.
25
+
26
+ ## Currently playing
27
+
28
+ To retrieve what is currently playing, use the asynchronous playing method:
29
+
30
+ ```python
31
+ playing = await atv.metadata.playing()
32
+ ```
33
+
34
+ You can easily extract fields like title, album or media type. See
35
+ {% include api i="interface.Playing" %}.
36
+
37
+ Support by protocol (assuming app sets metadata correctly):
38
+
39
+ * MRP: All fields
40
+ * DMAP: All except {% include api i="interface.Playing.series_name" %},
41
+ {% include api i="interface.Playing.season_number" %} and {% include api i="interface.Playing.episode_number" %}
42
+ * AirPlay and Companion: None
43
+
44
+ ## Artwork
45
+
46
+ To retrieve the artwork, use the asynchronous artwork method:
47
+
48
+ ```python
49
+ artwork = await atv.metadata.artwork()
50
+ ```
51
+
52
+ This will return an {% include api i="interface.ArtworkInfo" %}, containing the image bytes,
53
+ mimetype and dimensions. If no artwork is available, `None` is returned instead. If dimensions
54
+ could not be determined by the device, `width` and `height` will be set to -1.
55
+
56
+ It is also possible to request artwork with a particular size by passing `width` and `height`:
57
+
58
+ ```python
59
+ artwork = await atv.metadata.artwork(width=300, height=200)
60
+ ```
61
+
62
+ Do note that this is the desired size and the device might return artwork with another size,
63
+ e.g. to keep aspect ratio or if specified size it not available. You can pass `None` as one
64
+ of the arguments to let the device maintain aspect ratio of the image.
65
+
66
+ Remember that the artwork is relatively large, so you should try to minimize
67
+ this call. More information is available at {% include api i="interface.Metadata.artwork" %}.
68
+ Internally, a small cache is used for the last few requested artworks. The size of this cache
69
+ is not yet configurable and you should write a feature request if you need to change it.
70
+
71
+ ## Device identifier
72
+
73
+ The concept of *unique identifiers* was discussed in the
74
+ [concepts](../../documentation/concepts/#identifiers) section. You can retrieve one of the
75
+ identifiers via this property:
76
+
77
+ ```python
78
+ identifier = atv.metadata.device_id
79
+ ```
80
+
81
+ ## Hash
82
+
83
+ To simplify detection if content has changed between retrieval of what is
84
+ currently playing, a unique hash can be generated. It is a SHA256 hash based
85
+ on the following data:
86
+
87
+ - Title
88
+ - Artist
89
+ - Album
90
+ - Total time
91
+
92
+ These properties has been selected as they are in general unique for the same
93
+ content. No guarantee is however given that the same hash is not given for
94
+ different content nor the same content. It can be used as a fair guess.
95
+
96
+ ```python
97
+ playing = await atv.metadata.playing()
98
+ ... # Some time later
99
+ playing2 = await atv.metadata.playing()
100
+ if playing2.hash != playing.hash:
101
+ print('Content has changed')
102
+ ```
103
+
104
+ ## Active App
105
+
106
+ Is is possible to get information about the app that is currently playing something via
107
+ {% include api i="interface.Metadata.app" %}:
108
+
109
+ ```python
110
+ app = atv.metadata.app
111
+ print("Name:", app.name)
112
+ print("Identifier:", app.identifier)
113
+ ```
114
+
115
+ It conforms to the {% include api i="interface.App" %} interface.
@@ -0,0 +1,53 @@
1
+ ---
2
+ layout: template
3
+ title: Power Management
4
+ permalink: /development/power_management/
5
+ link_group: development
6
+ ---
7
+ # Power Management
8
+
9
+ Power management of a device is done with the power interface,
10
+ {% include api i="interface.Power" %}. It allows you to turn on, turn off and get current
11
+ power state. This interface is currently only supported by devices running tvOS.
12
+
13
+ ## Using the Power Management API
14
+
15
+ After connecting to a device, you get the power management via {% include api i="interface.AppleTV.power" %}:
16
+
17
+ ```python
18
+ atv = await pyatv.connect(config, ...)
19
+ pwrc = atv.power
20
+ ```
21
+
22
+ You can then control via the available functions:
23
+
24
+ ```python
25
+ await pwrc.turn_on()
26
+ await pwrc.turn_off()
27
+ ```
28
+
29
+ To get current power state use following property:
30
+
31
+ ```python
32
+ @property
33
+ def power_state(self) -> const.PowerState:
34
+ ```
35
+
36
+ ## Waiting for State Change
37
+
38
+ It is possible to pass `await_new_state` set to `True` when turning on
39
+ or off a device to have pyatv wait for a state change. E.g. calling
40
+ {% include api i="interface.Power.turn_off" %} will block until the device
41
+ has powered off:
42
+
43
+ ```python
44
+ await pwrc.turn_off(await_new_state=True)
45
+ ```
46
+
47
+ If the device is already off, it will return immediately.
48
+
49
+ To not block indefinitely, use `wait_for` with a timeout:
50
+
51
+ ```python
52
+ await asyncio.wait_for(pwrc.turn_off(await_new_state=True), timeout=5)
53
+ ```
@@ -0,0 +1,331 @@
1
+ ---
2
+ layout: template
3
+ title: Scan, Pair and Connect
4
+ permalink: /development/scan_pair_and_connect/
5
+ link_group: development
6
+ ---
7
+ # Table of Contents
8
+ {:.no_toc}
9
+ * TOC
10
+ {:toc}
11
+
12
+ # Scan, Pair and Connect
13
+
14
+ Finding a device, pairing with it and connecting to it are the basic actions needed
15
+ to control a device.
16
+
17
+ # Scan
18
+
19
+ Use {% include api i="pyatv.scan" %} to scan for devices on the local network.
20
+ Scanning for and printing name and address of discovered devices can be done like this:
21
+
22
+ ```python
23
+ atvs = await pyatv.scan(loop)
24
+ for atv in atvs:
25
+ print(f"Name: {atv.name}, Address: {atv.address}")
26
+ ```
27
+
28
+ You can put some limitations on what device(s) to scan for, e.g. an identifier
29
+ and/or a protocol:
30
+
31
+ ```python
32
+ from pyatv import scan
33
+ from pyatv.const import Protocol
34
+
35
+ # Scan for a specific device
36
+ atvs = scan(loop, identifier="AA:BB:CC:DD:EE:FF")
37
+
38
+ # Scan for a specific device by IP (unicast)
39
+ atvs = scan(loop, hosts=["10.0.0.1"])
40
+
41
+ # Only scan for MRP services
42
+ atvs = scan(loop, protocol=Protocol.MRP)
43
+
44
+ # Include both MRP and AirPlay
45
+ atvs = scan(loop, protocol={Protocol.MRP, Protocol.AirPlay})
46
+ ```
47
+
48
+ A list is always returned, even if a filter is applied. See
49
+ {% include api i="conf.AppleTV" %} for what you can do with a configuration
50
+ (e.g. extract deep sleep state or available services).
51
+
52
+ When scanning for one or more protocols with `protocols`, only the listed
53
+ protocols are added to the configuration regardless if more protocols are
54
+ supported.
55
+
56
+ It is possible to provide a `set` of identifiers to scan for:
57
+
58
+ ```python
59
+ atvs = scan(loop, identifier={"id1", "id2"})
60
+ ```
61
+
62
+ The first device responding to either of the identifiers will be returned.
63
+ This is useful when re-discovering a previous known device. Scanning for
64
+ all identifiers used by a device will work even if a service is no longer
65
+ present, e.g. when disabling AirPlay.
66
+
67
+ ## Enabled and disabled services
68
+
69
+ Each service has an *enabled* flag, indicating if pyatv should connect to the
70
+ service or not. The main reason for adding a disabled service in contrast to
71
+ ignoring it is that pyatv can extract device information from that service,
72
+ e.g. unique identifiers. This is for instance the case with MRP on tvOS 15,
73
+ where MRP no longer can be connected to but we still want to collect its
74
+ unique identifier.
75
+
76
+ # Pair
77
+
78
+ Calling {% include api i="pyatv.pair" %} returns a _pairing handler_ conforming to the interface
79
+ {% include api i="interface.PairingHandler" %}. The usage flow is generic in order to support
80
+ protocols that either require a PIN entered on the device (`DMAP`) or in the client
81
+ (`MRP` and `AirPlay`).
82
+
83
+ ## Pairing Requirement
84
+
85
+ Not all protocols support nor require pairing, it is thus necessary to verify if pairing is
86
+ needed before calling {% include api i="pyatv.pair" %}. After performing a scan, the
87
+ {% include api i="interface.BaseService.pairing" %} property return whether pairing is required
88
+ or not. There are five states to consider:
89
+
90
+ | Requirement | Meaning |
91
+ | ----------- | ------- |
92
+ | {% include api i="const.PairingRequirement.Unsupported" %} | Pairing is either not supported by protocol or not implemented by pyatv.
93
+ | {% include api i="const.PairingRequirement.Disabled" %} | Pairing is generally supported by the protocol, but has been (temporarily) disabled by the device.
94
+ | {% include api i="const.PairingRequirement.NotNeeded" %} | Pairing is not needed, i.e. it is possible to connect without any further action.
95
+ | {% include api i="const.PairingRequirement.Optional" %} | Pairing is not needed but recommended. One example is when Home Sharing is enabled, where credentials are included in the Zeroconf properties.
96
+ | {% include api i="const.PairingRequirement.Mandatory" %} | Pairing must be performed.
97
+
98
+ The pairing requirement is solely based on what is required by a protocol and does not take
99
+ any provided credentials into account, i.e. {% include api i="interface.BaseService.pairing" %}
100
+ will return {% include api i="const.PairingRequirement.Mandatory" %} even when credentials
101
+ are filled in.
102
+
103
+ {% include api i="pyatv.pair" %} must only be called if {% include api i="interface.BaseService.pairing" %}
104
+ is either {% include api i="const.PairingRequirement.Optional" %} or
105
+ {% include api i="const.PairingRequirement.Mandatory" %}.
106
+
107
+ ## Pairing Flow
108
+
109
+ The general flow for pairing looks like this.
110
+
111
+ 1. Start pairing by calling `begin`
112
+ 2. Check if device presents a PIN by checking `device_provides_pin`
113
+ * If True: call `pin` with the PIN shown on screen
114
+ * If False: call `pin` with the PIN that must be
115
+ entered on the device and wait for user to enter PIN
116
+ 3. Call `finish`
117
+ 4. Check if pairing succeeded with `has_paired`
118
+ 5. Free resources with `close`
119
+ 6. Obtained credentials are available via the service, i.e. `service.credentials`
120
+
121
+ In a future revision of this API, a function will be added that waits for the pairing
122
+ to succeed (or timeout), in order to know when to call `finish`. This is only applicable
123
+ to the case when `device_provides_pin` is False. Now you have to poll `has_paired` or
124
+ just require that pairing succeeds within a time frame.
125
+
126
+ If an error occurs, e.g. incorrect PIN, {% include api i="exceptions.PairingError" %} is raised.
127
+
128
+ Translating the flow above into code looks like this (this is a simplified version of `examples/pairing.py`):
129
+
130
+ ```python
131
+ import asyncio
132
+ from pyatv import scan, pair
133
+ from pyatv.const import Protocol
134
+
135
+ async def main():
136
+ loop = asyncio.get_event_loop()
137
+
138
+ atvs = await scan(loop)
139
+
140
+ pairing = await pair(atvs[0], Protocol.MRP, loop)
141
+ await pairing.begin()
142
+
143
+ if pairing.device_provides_pin:
144
+ pin = int(input("Enter PIN: "))
145
+ pairing.pin(pin)
146
+ else:
147
+ pairing.pin(1234) # Should be randomized
148
+ input("Enter this PIN on the device: 1234")
149
+
150
+ await pairing.finish()
151
+
152
+ # Give some feedback about the process
153
+ if pairing.has_paired:
154
+ print("Paired with device!")
155
+ print("Credentials:", pairing.service.credentials)
156
+ else:
157
+ print("Did not pair with device!")
158
+
159
+ await pairing.close()
160
+
161
+ asyncio.run(main()) # asyncio.run requires python 3.7+
162
+ ```
163
+
164
+ ## Storing Credentials
165
+
166
+ Since pyatv 0.14.0, credentials and passwords are managed by a storage module. This means that
167
+ credentials may be stored automatically to for instance a file or cloud service after pairing. It
168
+ also allows for loading of said properties automatically. Please see
169
+ [Storage and Settings](../storage) for details on using a storage module.
170
+
171
+ ### Legacy Storing Credentials
172
+
173
+ Prior to storage support, credentials would be stored like this:
174
+
175
+ ```python
176
+ identifier = const.identifier
177
+
178
+ # Save identifier
179
+
180
+ for service in config.services:
181
+ protocol = service.protocol
182
+ credentials = service.credentials
183
+
184
+ # Save mapping of protocol and credentials
185
+ ```
186
+
187
+ How to restore credentials is described in [here](#restoring-credentials).
188
+
189
+ ## Protocol specific settings
190
+
191
+ Some protocols support protocol specific setting, e.g. a special name or
192
+ identifier. Prior to pyatv 0.14.0 these settings would be passed as
193
+ additional arguments to {% include api i="pyatv.pair" %}. Settings are now
194
+ stored in storage, so to change these settings you should update settings
195
+ for the device in storage instead.
196
+
197
+ ### DMAP specifics (deprecated)
198
+
199
+ *Note: Settings should be set via the settings API as of pyatv 0.14.0. Please refer to
200
+ [Changing Settings](../storage/#changing-settings) for help with changing settings. The table below
201
+ refers to the corresponding setting in storage (when applicable and supported).*
202
+
203
+ The following extra settings are supported by `DMAP`:
204
+
205
+ | Setting | Value | Storage |
206
+ | ------- | ----- | ------- |
207
+ | name | Name of the device that is exposed on the network (what you see on your Apple TV). | {% include api i="settings.InfoSettings.name" %}
208
+ | pairing_guid | Custom value for `pairing_guid` (credentials) with format `0xXXXXXXXXXXXXXXXX`. | Not supported (yet)
209
+ | zeroconf | If you want to use a custom `zeroconf.Zeroconf` instance, you can pass it here. | Not supported (yet)
210
+ | addresses | List of local addresses to broadcast Zeroconf service on, e.g. `["10.0.0.1", "192.168.1.2"]`. | Not supported (yet)
211
+
212
+ Apply setting according to:
213
+
214
+ ```python
215
+ # Using pyatv.pair directly
216
+ pairing = await pyatv.pair(config, Protocol.DMAP, name="my remote")
217
+
218
+ # Updating setting, then calling pyatv.pair
219
+ settings = await storage.get_settings(conf)
220
+ settings.info.name = "my remote"
221
+
222
+ pairing = await pyatv.pair(config, Protocol.DMAP)
223
+ ```
224
+
225
+ # Connect
226
+
227
+ Connecting is simply done by passing a config to {% include api i="pyatv.connect" %}:
228
+
229
+ ```python
230
+ # Get a configuration with scan
231
+ atvs = await pyatv.scan(...)
232
+
233
+ # Apple TV configuration (first found device in this case)
234
+ conf = atvs[0]
235
+
236
+ # Connect with obtained configuration
237
+ atv = await pyatv.connect(atvs[0], loop)
238
+ ```
239
+
240
+ If the configuration contains no services (only possible when manually
241
+ creating a config), a {% include api i="exceptions.NoServiceError" %} will
242
+ be raised. The configuration must have an `identifier`, otherwise
243
+ {% include api i="exceptions.DeviceIdMissingError" %} will be raised.
244
+
245
+ If you have previously stored any credentials, you can need to load them again before
246
+ connecting, see next chapter.
247
+
248
+ *Note: Prior to version 0.8.0, the protocol argument specified which "main"
249
+ protocol to use. This is no longer needed as the most appropriate protocol
250
+ will be used automatically.*
251
+
252
+ ## Restoring credentials
253
+
254
+ When using a storage module, credentials will be loaded automatically without any additional code.
255
+ See [Storage and Settings](../storage) for details on settings that up.
256
+
257
+ Legacy method of restoring credentials is performed with {% include api i="conf.AppleTV.set_credentials" %}:
258
+
259
+ ```python
260
+ # Restored from file
261
+ identifier = "..."
262
+ stored_credentials = {Protocol.MRP: "xxx"}
263
+
264
+ # Find device and restore credentials
265
+ atvs = pyatv.scan(loop, identifier=identifier)
266
+
267
+ # Error handling here
268
+
269
+ atv = atvs[0]
270
+ for protocol, credentials in stored_credentials.items():
271
+ atv.set_credentials(protocol, credentials)
272
+ ```
273
+
274
+ True is returned if credentials were set, otherwise False.
275
+
276
+ ## Manual configuration
277
+
278
+ It is possible to bypass the scanning process and manually create a configuration:
279
+
280
+ ```python
281
+ service = conf.ManualService(
282
+ "identifier", Protocol.DMAP, 3689, {}, credentials="0x123456789ABCDEF0"
283
+ )
284
+ config = conf.AppleTV("10.0.0.10", "Living Room")
285
+ config.add_service(service)
286
+ atv = await pyatv.connect(config, loop)
287
+ ```
288
+
289
+ Please do note that this is not the recommended way as it has a couple of flaws:
290
+
291
+ * Name and IP-adress might not match the device you expect
292
+ * The identifier passed to the service does not make any sense and is not unique anymore
293
+ * Dynamic properties, like port numbers, will cause problems
294
+
295
+ It can however be convenient to have if you test things when developing pyatv
296
+ as you can shorten the feedback loop, since scanning can be avoided. But be warned.
297
+
298
+ A service is by default *enabled*, meaning that pyatv will try to connect to the
299
+ service when {% include api i="pyatv.connect" %} is called. It is possible to add
300
+ a service but not connect to it by setting `enabled` to `False`:
301
+
302
+ ```python
303
+ service = conf.ManualService(
304
+ "identifier", Protocol.DMAP, 3689, {}, enabled=False
305
+ )
306
+ config = conf.AppleTV("10.0.0.10", "Living Room")
307
+ config.add_service(service)
308
+ atv = await pyatv.connect(config, loop)
309
+ ```
310
+
311
+ *NB: Service specific services, e.g. {% include api i="conf.DmapService" %} is deprecated
312
+ as of 0.9.0. Please use {% include api i="conf.ManualService" %} instead.*
313
+
314
+ ## Closing connection
315
+
316
+ To close the connection, use {% include api i="interface.AppleTV.close" %}:
317
+
318
+ ```python
319
+ atv = await pyatv.connect(config, loop)
320
+
321
+ # Do something
322
+
323
+ atv.close()
324
+ ```
325
+
326
+ A set of pending tasks are returned by {% include api i="interface.AppleTV.close" %},
327
+ which can be awaited to make sure everything has been torn down:
328
+
329
+ ```python
330
+ await asyncio.gather(*atv.close())
331
+ ```
@@ -0,0 +1,9 @@
1
+ ---
2
+ layout: template
3
+ title: Services
4
+ permalink: /development/services/
5
+ link_group: development
6
+ ---
7
+ # Services
8
+
9
+ This page has not yet been migrated to GitHub Pages. Come back later...