Een Holographic Remoting Remote-app schrijven met behulp van de HolographicSpace-API
Als u geen gebruik hebt van Holographic Remoting, kunt u ons overzicht lezen.
Belangrijk
In dit document wordt beschreven hoe u een externe toepassing maakt voor HoloLens 2 met behulp van de HolographicSpace-API. Externe toepassingen voor HoloLens (1e generatie) moeten NuGet-pakketversie 1.x.x gebruiken. Dit betekent dat externe toepassingen die zijn geschreven voor HoloLens 2 niet compatibel zijn met HoloLens 1 en vice versa. De documentatie voor HoloLens 1 vindt u hier.
Kennisgeving over afschaffing: de releaseregel 2.9.x is de laatste die Ondersteuning biedt voor Windows Holographic API's voor het ontwikkelen van toepassingen. Toekomstige versies ondersteunen alleen OpenXR voor het ontwikkelen van toepassingen. Onafhankelijk van dat raden we het gebruik van OpenXR in uw toepassing aan voor alle nieuwe toepassingsontwikkeling. Bestaande toepassingen die 2.9 of ouder gebruiken, blijven werken zonder dat dit wordt beïnvloed door toekomstige wijzigingen.
Holografische externe apps kunnen extern weergegeven inhoud streamen naar HoloLens 2 en Windows Mixed Reality immersive headsets. U kunt ook toegang krijgen tot meer systeembronnen en externe insluitende weergaven integreren in bestaande desktop-pc-software. Een externe app ontvangt een invoergegevensstroom van HoloLens 2, geeft inhoud weer in een virtuele insluitende weergave en streamt inhoudsframes terug naar HoloLens 2. De verbinding wordt gemaakt met behulp van standaard Wi-Fi. Holografische externe communicatie wordt toegevoegd aan een desktop- of UWP-app via een NuGet-pakket. Er is aanvullende code vereist waarmee de verbinding wordt verwerkt en in een insluitende weergave wordt weergegeven. Een typische externe verbinding heeft een lage latentie van wel 50 ms. De speler-app kan de latentie in realtime rapporteren.
Alle code op deze pagina en werkprojecten zijn te vinden in de GitHub-opslagplaats holographic Remoting-voorbeelden.
Vereisten
Een goed uitgangspunt is een werkende desktop- of UWP-app op basis van DirectX die is gericht op de Windows Mixed Reality API. Zie Overzicht van DirectX-ontwikkeling voor meer informatie. De holografische C++-projectsjabloon is een goed uitgangspunt.
Belangrijk
Elke app die gebruikmaakt van Holographic Remoting moet worden geschreven voor het gebruik van een appartement met meerdere threads. Het gebruik van een appartement met één schroefdraad wordt ondersteund, maar leidt tot suboptimale prestaties en mogelijk haperingen tijdens het afspelen. Wanneer u C++/WinRT winrt::init_apartment is een appartement met meerdere threads de standaardinstelling.
Download het Holographic Remoting NuGet-pakket
De volgende stappen zijn vereist om het NuGet-pakket toe te voegen aan een project in Visual Studio.
- Open het project in Visual Studio.
- Klik met de rechtermuisknop op het projectknooppunt en selecteer NuGet-pakketten beheren...
- Selecteer bladeren in het deelvenster dat wordt weergegeven en zoek vervolgens naar 'Holographic Remoting'.
- Selecteer Microsoft.Holographic.Remoting, zorg ervoor dat u de nieuwste versie 2.x.x kiest en selecteer Installeren.
- Als het dialoogvenster Voorbeeld wordt weergegeven, selecteert u OK.
- Selecteer Ik ga akkoord wanneer het dialoogvenster met de licentieovereenkomst wordt weergegeven.
Notitie
Versie 1.x.x van het NuGet-pakket is nog steeds beschikbaar voor ontwikkelaars die holoLens 1 willen targeten. Zie HoloOgraphic Remoting (HoloLens (1e generatie) toevoegen voor meer informatie.
De externe context maken
Als eerste stap moet de toepassing een externe context maken.
// class declaration
#include <winrt/Microsoft.Holographic.AppRemoting.h>
...
private:
// RemoteContext used to connect with a Holographic Remoting player and display rendered frames
winrt::Microsoft::Holographic::AppRemoting::RemoteContext m_remoteContext = nullptr;
// class implementation
#include <HolographicAppRemoting\Streamer.h>
...
CreateRemoteContext(m_remoteContext, 20000, false, PreferredVideoCodec::Default);
Waarschuwing
Holographic Remoting werkt door de Windows Mixed Reality runtime die deel uitmaakt van Windows te vervangen door een specifieke runtime voor externe communicatie. Dit wordt gedaan tijdens het maken van de externe context. Daarom kan elke aanroep op een Windows Mixed Reality-API voordat de externe context wordt gemaakt, leiden tot onverwacht gedrag. De aanbevolen aanpak is om de externe context zo vroeg mogelijk te maken vóór interactie met een Mixed Reality API. Meng nooit objecten die zijn gemaakt of opgehaald via een Windows Mixed Reality API vóór de aanroep van CreateRemoteContext met objecten die later zijn gemaakt of opgehaald.
Vervolgens moet de holografische ruimte worden gemaakt. Het opgeven van een CoreWindow is niet vereist. Bureaublad-apps die geen CoreWindow hebben, kunnen gewoon een nullptr
doorgeven.
m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(nullptr);
Verbinding maken met het apparaat
Wanneer de externe app gereed is voor het weergeven van inhoud, kan er een verbinding met het spelerapparaat tot stand worden gebracht.
U kunt op twee manieren verbinding maken.
- De externe app maakt verbinding met de speler die op het apparaat wordt uitgevoerd.
- De speler die op het apparaat wordt uitgevoerd, maakt verbinding met de externe app.
Als u een verbinding tot stand wilt brengen tussen de externe app en het spelerapparaat, roept u de Connect
methode aan in de externe context en geeft u de hostnaam en poort op. De poort die wordt gebruikt door de Holographic Remoting Player is 8265.
try
{
m_remoteContext.Connect(m_hostname, m_port);
}
catch(winrt::hresult_error& e)
{
DebugLog(L"Connect failed with hr = 0x%08X", e.code());
}
Belangrijk
Net als bij elke C++/WinRT-API Connect
kan een winrt::hresult_error genereren die moet worden verwerkt.
Tip
Om het gebruik van C++/WinRT-taalprojectie te voorkomen, kan het bestand build\native\include\<windows sdk version>\abi\Microsoft.Holographic.AppRemoting.h
in het Holographic Remoting NuGet-pakket worden opgenomen. Het bevat declaraties van de onderliggende COM-interfaces. Het gebruik van C++/WinRT wordt echter aanbevolen.
Luisteren naar binnenkomende verbindingen in de externe app kan worden uitgevoerd door de Listen
methode aan te roepen. Zowel de handshakepoort als de transportpoort kunnen tijdens deze aanroep worden opgegeven. De handshakepoort wordt gebruikt voor de eerste handshake. De gegevens worden vervolgens verzonden via de transportpoort. Standaard worden 8265 en 8266 gebruikt.
try
{
m_remoteContext.Listen(L"0.0.0.0", m_port, m_port + 1);
}
catch(winrt::hresult_error& e)
{
DebugLog(L"Listen failed with hr = 0x%08X", e.code());
}
Belangrijk
De build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl
in het NuGet-pakket bevat gedetailleerde documentatie voor de API die wordt weergegeven door Holographic Remoting.
Afhandeling van specifieke gebeurtenissen voor externe communicatie
In de externe context worden drie gebeurtenissen weergegeven, die belangrijk zijn voor het bewaken van de status van een verbinding.
- OnConnected: wordt geactiveerd wanneer een verbinding met het apparaat tot stand is gebracht.
winrt::weak_ref<winrt::Microsoft::Holographic::AppRemoting::IRemoteContext> remoteContextWeakRef = m_remoteContext;
m_onConnectedEventRevoker = m_remoteContext.OnConnected(winrt::auto_revoke, [this, remoteContextWeakRef]() {
if (auto remoteContext = remoteContextWeakRef.get())
{
// Update UI state
}
});
- OnDisconnected: wordt geactiveerd als een tot stand gebrachte verbinding is gesloten of als er geen verbinding tot stand kan worden gebracht.
m_onDisconnectedEventRevoker =
m_remoteContext.OnDisconnected(winrt::auto_revoke, [this, remoteContextWeakRef](ConnectionFailureReason failureReason) {
if (auto remoteContext = remoteContextWeakRef.get())
{
DebugLog(L"Disconnected with reason %d", failureReason);
// Update UI
// Reconnect if this is a transient failure.
if (failureReason == ConnectionFailureReason::HandshakeUnreachable ||
failureReason == ConnectionFailureReason::TransportUnreachable ||
failureReason == ConnectionFailureReason::ConnectionLost)
{
DebugLog(L"Reconnecting...");
ConnectOrListen();
}
// Failure reason None indicates a normal disconnect.
else if (failureReason != ConnectionFailureReason::None)
{
DebugLog(L"Disconnected with unrecoverable error, not attempting to reconnect.");
}
}
});
- OnListening: wanneer het luisteren naar binnenkomende verbindingen wordt gestart.
m_onListeningEventRevoker = m_remoteContext.OnListening(winrt::auto_revoke, [this, remoteContextWeakRef]() {
if (auto remoteContext = remoteContextWeakRef.get())
{
// Update UI state
}
});
Daarnaast kan de verbindingsstatus worden opgevraagd met behulp van de ConnectionState
eigenschap in de externe context.
auto connectionState = m_remoteContext.ConnectionState();
Spraakevenementen verwerken
Met behulp van de externe spraakinterface is het mogelijk om spraaktriggers te registreren met HoloLens 2 en deze op afstand naar de externe toepassing te laten uitvoeren.
Het volgende extra lid is vereist om de status van de externe spraak bij te houden:
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker m_onRecognizedSpeechRevoker;
Haal eerst de externe spraakinterface op.
if (auto remoteSpeech = m_remoteContext.GetRemoteSpeech())
{
InitializeSpeechAsync(remoteSpeech, m_onRecognizedSpeechRevoker, weak_from_this());
}
Met behulp van een asynchrone helpermethode kunt u vervolgens de externe spraak initialiseren. Dit moet asynchroon worden gedaan, omdat initialisatie veel tijd kan kosten. Gelijktijdigheid en asynchrone bewerkingen met C++/WinRT legt uit hoe u asynchrone functies kunt maken met C++/WinRT.
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::Storage::StorageFile> LoadGrammarFileAsync()
{
const wchar_t* speechGrammarFile = L"SpeechGrammar.xml";
auto rootFolder = winrt::Windows::ApplicationModel::Package::Current().InstalledLocation();
return rootFolder.GetFileAsync(speechGrammarFile);
}
winrt::fire_and_forget InitializeSpeechAsync(
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech remoteSpeech,
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker& onRecognizedSpeechRevoker,
std::weak_ptr<SampleRemoteMain> sampleRemoteMainWeak)
{
onRecognizedSpeechRevoker = remoteSpeech.OnRecognizedSpeech(
winrt::auto_revoke, [sampleRemoteMainWeak](const winrt::Microsoft::Holographic::AppRemoting::RecognizedSpeech& recognizedSpeech) {
if (auto sampleRemoteMain = sampleRemoteMainWeak.lock())
{
sampleRemoteMain->OnRecognizedSpeech(recognizedSpeech.RecognizedText);
}
});
auto grammarFile = co_await LoadGrammarFileAsync();
std::vector<winrt::hstring> dictionary;
dictionary.push_back(L"Red");
dictionary.push_back(L"Blue");
dictionary.push_back(L"Green");
dictionary.push_back(L"Default");
dictionary.push_back(L"Aquamarine");
remoteSpeech.ApplyParameters(L"", grammarFile, dictionary);
}
Er zijn twee manieren om zinnen op te geven die moeten worden herkend.
- Specificatie in een XML-bestand met spraak grammatica. Zie How to create a basic XML Grammar (Een eenvoudige XML-grammatica maken) voor meer informatie.
- Geef op door ze in de woordenlijstvector door te geven aan
ApplyParameters
.
In de callback OnRecognizedSpeech kunnen de spraakgebeurtenissen vervolgens worden verwerkt:
void SampleRemoteMain::OnRecognizedSpeech(const winrt::hstring& recognizedText)
{
bool changedColor = false;
DirectX::XMFLOAT4 color = {1, 1, 1, 1};
if (recognizedText == L"Red")
{
color = {1, 0, 0, 1};
changedColor = true;
}
else if (recognizedText == L"Blue")
{
color = {0, 0, 1, 1};
changedColor = true;
}
else if (recognizedText == L"Green")
{
...
}
...
}
Lokaal gestreamde inhoud bekijken
Als u dezelfde inhoud wilt weergeven in de externe app die naar het apparaat wordt verzonden, kan de OnSendFrame
gebeurtenis van de externe context worden gebruikt. De OnSendFrame
gebeurtenis wordt geactiveerd telkens wanneer de Holographic Remoting-bibliotheek het huidige frame naar het externe apparaat verzendt. Dit is het ideale moment om de inhoud te nemen en ook in het bureaublad- of UWP-venster te snijden.
#include <windows.graphics.directx.direct3d11.interop.h>
...
m_onSendFrameEventRevoker = m_remoteContext.OnSendFrame(
winrt::auto_revoke, [this](const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface& texture) {
winrt::com_ptr<ID3D11Texture2D> texturePtr;
{
winrt::com_ptr<ID3D11Resource> resource;
winrt::com_ptr<::IInspectable> inspectable = texture.as<::IInspectable>();
winrt::com_ptr<Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess> dxgiInterfaceAccess;
winrt::check_hresult(inspectable->QueryInterface(__uuidof(dxgiInterfaceAccess), dxgiInterfaceAccess.put_void()));
winrt::check_hresult(dxgiInterfaceAccess->GetInterface(__uuidof(resource), resource.put_void()));
resource.as(texturePtr);
}
// Copy / blit texturePtr into the back buffer here.
});
Diepteherprojectie
Vanaf versie 2.1.0 ondersteunt Holographic Remoting Diepteherprojectie. Hiervoor moeten zowel de kleurbuffer als de dieptebuffer worden gestreamd van de externe toepassing naar de HoloLens 2. Dieptebufferstreaming is standaard ingeschakeld en geconfigureerd om de helft van de resolutie van de kleurbuffer te gebruiken. Dit kan als volgt worden gewijzigd:
// class implementation
#include <HolographicAppRemoting\Streamer.h>
...
CreateRemoteContext(m_remoteContext, 20000, false, PreferredVideoCodec::Default);
// Configure for half-resolution depth.
m_remoteContext.ConfigureDepthVideoStream(DepthBufferStreamResolution::Half_Resolution);
Als standaardwaarden niet moeten worden gebruiktConfigureDepthVideoStream
, moet u aangeroepen worden voordat er een verbinding met de HoloLens 2 tot stand wordt gebracht. De beste plaats is direct nadat u de externe context hebt gemaakt. Mogelijke waarden voor DepthBufferStreamResolution zijn:
- Full_Resolution
- Half_Resolution
- Quarter_Resolution
- Uitgeschakeld (toegevoegd met versie 2.1.3 en bij gebruik wordt er geen extra dieptevideostream gemaakt)
Houd er rekening mee dat het gebruik van een dieptebuffer voor volledige resolutie ook van invloed is op de bandbreedtevereisten en moet worden meegenomen in de maximale bandbreedtewaarde die u opgeeft aan CreateRemoteContext
.
Naast het configureren van de resolutie moet u ook een dieptebuffer doorvoeren via HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer.
void SampleRemoteMain::Render(HolographicFrame holographicFrame)
{
...
m_deviceResources->UseHolographicCameraResources([this, holographicFrame](auto& cameraResourceMap) {
...
for (auto cameraPose : prediction.CameraPoses())
{
DXHelper::CameraResources* pCameraResources = cameraResourceMap[cameraPose.HolographicCamera().Id()].get();
...
m_deviceResources->UseD3DDeviceContext([&](ID3D11DeviceContext3* context) {
...
// Commit depth buffer if available and enabled.
if (m_canCommitDirect3D11DepthBuffer && m_commitDirect3D11DepthBuffer)
{
auto interopSurface = pCameraResources->GetDepthStencilTextureInteropObject();
HolographicCameraRenderingParameters renderingParameters = holographicFrame.GetRenderingParameters(cameraPose);
renderingParameters.CommitDirect3D11DepthBuffer(interopSurface);
}
});
}
});
}
Als u wilt controleren of diepteherprojectie correct werkt op HoloLens 2, kunt u een diepte visualiseren via de apparaatportal. Zie Controleren of diepte juist is ingesteld voor meer informatie.
Optioneel: Aangepaste gegevenskanalen
Aangepaste gegevenskanalen kunnen worden gebruikt om gebruikersgegevens te verzenden via de reeds tot stand gebrachte externe verbinding. Zie Aangepaste gegevenskanalen voor meer informatie.
Optioneel: Systeemsynchronisatie coördineren
Vanaf versie 2.7.0 kan systeemsynchronisatie coördineren worden gebruikt om ruimtelijke gegevens uit te lijnen tussen de speler en de externe toepassing. Zie Systeemsynchronisatie coördineren met Holographic Remoting Overview (Overzicht van externe communicatie met Holographic) voor meer informatie.
Zie ook
- Overzicht van Holoographic Remoting
- Een aangepaste Holographic Remoting-speler-app schrijven
- Aangepaste Holographic Remoting-gegevenskanalen
- Een beveiligde verbinding tot stand brengen met Holographic Remoting
- Problemen en beperkingen voor holografische externe communicatie oplossen
- Licentievoorwaarden voor software voor externe communicatie van Holographic
- Privacyverklaring van Microsoft