Holographic Remoting Remote alkalmazás írása a HolographicSpace API használatával
Ha még nem ismerkedik a Holographic Remoting használatával, érdemes elolvasnia az áttekintést.
Fontos
Ez a dokumentum egy távoli alkalmazás létrehozását ismerteti HoloLens 2 a HolographicSpace API használatával. A HoloLens távoli alkalmazásainak (1. generációs)NuGet-csomag 1.x.x-es verzióját kell használniuk. Ez azt jelenti, hogy a HoloLens 2 írt távoli alkalmazások nem kompatibilisek a HoloLens 1-zel, és fordítva. A HoloLens 1 dokumentációja itt található.
Elavulási értesítés: A 2.9.x kiadási sor lesz az utolsó, amely támogatja a Windows Holographic API-kat az alkalmazásfejlesztéshez. A közelgő verziók csak az OpenXR-t támogatják az alkalmazásfejlesztéshez. Ebbôl függetlenül javasoljuk, hogy minden új alkalmazásfejlesztéshez használja az OpenXR-t az alkalmazásban. A 2.9-es vagy újabb verziót használó meglévő alkalmazások továbbra is működni fognak a közelgő változásoktól függetlenül.
A Holographic Remoting-alkalmazások távolról renderelt tartalmakat streamelhetnek HoloLens 2 és Windows Mixed Reality magával ragadó fejhallgatókba. Emellett több rendszererőforrást is elérhet, és távoli , modern nézeteket integrálhat a meglévő asztali pc-szoftverekbe. A távoli alkalmazások bemeneti adatstreamet kapnak HoloLens 2, virtuális, modern nézetben renderelik a tartalmat, és a tartalomkereteket visszaküldik HoloLens 2. A kapcsolat standard Wi-Fi-vel jön létre. A holografikus remoting nuGet-csomagon keresztül kerül egy asztali vagy UWP-alkalmazásba. További kódra van szükség, amely kezeli a kapcsolatot, és magával ragadó nézetben jelenik meg. Egy tipikus újraegyenlítési kapcsolat 50 ms késéssel fog rendelkezni. A lejátszóalkalmazás valós időben jelentheti a késést.
Ezen a lapon és a munkaprojektekben található összes kód megtalálható a Holographic Remoting samples github-adattárban.
Előfeltételek
Jó kiindulópont egy működő DirectX-alapú asztali vagy UWP-alkalmazás, amely a Windows Mixed Reality API-t célozza meg. Részletekért lásd: DirectX-fejlesztés áttekintése. A C++ holografikus projektsablon jó kiindulópont.
Fontos
A Holographic Remotingot használó alkalmazásokat többszálú lakás használatához kell létrehozni. Az egyszálas lakás használata támogatott, de a lejátszás során az optimálisnál rosszabb teljesítményhez és esetleg akadozáshoz vezet. A C++/WinRT winrt::init_apartment használata esetén a többszálas apartman az alapértelmezett.
A Holographic Remoting NuGet-csomag lekérése
A NuGet-csomag Visual Studióban való hozzáadásához a következő lépések szükségesek.
- Nyissa meg a projektet a Visual Studióban.
- Kattintson a jobb gombbal a projektcsomópontra, és válassza a NuGet-csomagok kezelése... lehetőséget.
- A megjelenő panelen válassza a Tallózás lehetőséget, majd keressen rá a "Holographic Remoting" kifejezésre.
- Válassza a Microsoft.Holographic.Remoting lehetőséget, válassza ki a legújabb 2.x.x verziót, és válassza a Telepítés lehetőséget.
- Ha megjelenik az Előnézet párbeszédpanel, válassza az OK gombot.
- Válassza az Elfogadom lehetőséget, amikor megjelenik a licencszerződés párbeszédpanel.
Megjegyzés
A NuGet-csomag 1.x.x-es verziója továbbra is elérhető a HoloLens 1-et megcélzó fejlesztők számára. További információ: HoloLens hozzáadása (1. generációs).
A távoli környezet létrehozása
Első lépésként az alkalmazásnak létre kell hoznia egy távoli környezetet.
// 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);
Figyelmeztetés
A Holographic Remoting úgy működik, hogy lecseréli a Windows részét képező Windows Mixed Reality futtatókörnyezetet egy adott futtatókörnyezetre. Ez a távoli környezet létrehozásakor történik. Ezért a távoli környezet létrehozása előtt bármely Windows Mixed Reality API-n történő hívás váratlan viselkedést eredményezhet. Az ajánlott módszer a távoli környezet lehető legkorábbi létrehozása, mielőtt bármilyen Mixed Reality API-val kommunikál. Soha ne keverje össze az Windows Mixed Reality API-val létrehozott vagy lekért objektumokat, mielőtt a CreateRemoteContext metódust meghívja a később létrehozott vagy lekért objektumokkal.
Ezután létre kell hozni a holografikus helyet. A CoreWindow megadása nem kötelező. Azok az asztali alkalmazások, amelyek nem rendelkeznek CoreWindowval, egyszerűen átadhatnak egy parancsot nullptr
.
m_holographicSpace = winrt::Windows::Graphics::Holographic::HolographicSpace::CreateForCoreWindow(nullptr);
Csatlakozás az eszközhöz
Ha a távoli alkalmazás készen áll a tartalom renderelésére, létre lehet hozni egy kapcsolatot a lejátszóeszközrel.
A kapcsolat kétféleképpen végezhető el.
- A távoli alkalmazás csatlakozik az eszközön futó lejátszóhoz.
- Az eszközön futó lejátszó csatlakozik a távoli alkalmazáshoz.
Ha kapcsolatot szeretne létesíteni a távoli alkalmazás és a lejátszóeszköz között, hívja meg a Connect
metódust a távoli környezetben, megadva a gazdagépnevet és a portot. A Holographic Remoting Player által használt port 8265.
try
{
m_remoteContext.Connect(m_hostname, m_port);
}
catch(winrt::hresult_error& e)
{
DebugLog(L"Connect failed with hr = 0x%08X", e.code());
}
Fontos
A C++/WinRT API-hoz Connect
hasonlóan a winrt::hresult_error is, amelyet kezelni kell.
Tipp
A C++/WinRT nyelvi kivetítés használatának elkerülése érdekében a Holographic Remoting NuGet-csomagban található fájl build\native\include\<windows sdk version>\abi\Microsoft.Holographic.AppRemoting.h
belefoglalható. A mögöttes COM-felületek deklarációit tartalmazza. A C++/WinRT használata azonban ajánlott.
A távoli alkalmazás bejövő kapcsolatainak figyelése a metódus meghívásával Listen
végezhető el. A hívás során a kézfogási port és az átviteli port is megadható. A kézfogási port a kezdeti kézfogáshoz használatos. Az adatok ezután az átviteli porton keresztül lesznek elküldve. Alapértelmezés szerint a 8265 és a 8266 van használatban.
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());
}
Fontos
A build\native\include\HolographicAppRemoting\Microsoft.Holographic.AppRemoting.idl
NuGet-csomagon belül részletes dokumentáció található a Holographic Remoting által közzétett API-hoz.
Adott események újraegyenlítésének kezelése
A távoli környezet három eseményt tesz elérhetővé, amelyek fontosak a kapcsolat állapotának monitorozásához.
- OnConnected: Akkor aktiválódik, ha sikerült kapcsolatot létesíteni az eszközzel.
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: Akkor aktiválódik, ha egy létrehozott kapcsolat lezárult, vagy nem sikerült kapcsolatot létesíteni.
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: A bejövő kapcsolatok figyelésekor elindul.
m_onListeningEventRevoker = m_remoteContext.OnListening(winrt::auto_revoke, [this, remoteContextWeakRef]() {
if (auto remoteContext = remoteContextWeakRef.get())
{
// Update UI state
}
});
Emellett a kapcsolati állapot lekérdezhető a ConnectionState
távoli környezet tulajdonságával.
auto connectionState = m_remoteContext.ConnectionState();
Beszédesemények kezelése
A távoli beszédfelület használatával regisztrálhatja a beszédindítókat a HoloLens 2, és távolról is el lehet őket távolíteni a távoli alkalmazáshoz.
A távoli beszéd állapotának nyomon követéséhez a következő további tagra van szükség:
winrt::Microsoft::Holographic::AppRemoting::IRemoteSpeech::OnRecognizedSpeech_revoker m_onRecognizedSpeechRevoker;
Először kérje le a távoli beszédfelületet.
if (auto remoteSpeech = m_remoteContext.GetRemoteSpeech())
{
InitializeSpeechAsync(remoteSpeech, m_onRecognizedSpeechRevoker, weak_from_this());
}
Aszinkron segédmetódussal inicializálhatja a távoli beszédet. Ezt aszinkron módon kell elvégezni, mivel az inicializálás jelentős időt vehet igénybe. Az egyidejűség és aszinkron műveletek a C++/WinRT használatával ismerteti, hogyan lehet aszinkron függvényeket létrehozni a C++/WinRT használatával.
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);
}
A felismerendő kifejezések megadásának két módja van.
- Specifikáció egy beszédhelyességi XML-fájlban. A részletekért lásd: Alapszintű XML-nyelvhelyesség létrehozása .
- Adja meg őket a szótárvektoron belül a következőnek
ApplyParameters
: .
Az OnRecognizedSpeech visszahíváson belül a beszédesemények ezután feldolgozhatók:
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")
{
...
}
...
}
Streamelt tartalom előzetes verziója helyileg
Ha ugyanazt a tartalmat szeretné megjeleníteni a távoli alkalmazásban, amelyet a rendszer az eszközre OnSendFrame
küld, a távoli környezet eseménye használható. Az OnSendFrame
esemény minden alkalommal aktiválódik, amikor a Holographic Remoting kódtár elküldi az aktuális keretet a távoli eszköznek. Ez az ideális alkalom arra, hogy a tartalmat az asztalra vagy az UWP-ablakba is becsomagolja.
#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.
});
Mélységi újraprojection
A 2.1.0-s verziótól kezdve a Holographic Remoting támogatja a mélységi újraprojektezést. Ehhez a színpuffert és a mélységi puffert is streamelni kell a távoli alkalmazásból a HoloLens 2. Alapértelmezés szerint a mélységi puffer streamelése engedélyezve van, és úgy van konfigurálva, hogy a színpuffer felbontásának felét használja. Ez a következőképpen módosítható:
// class implementation
#include <HolographicAppRemoting\Streamer.h>
...
CreateRemoteContext(m_remoteContext, 20000, false, PreferredVideoCodec::Default);
// Configure for half-resolution depth.
m_remoteContext.ConfigureDepthVideoStream(DepthBufferStreamResolution::Half_Resolution);
Vegye figyelembe, hogy ha az alapértelmezett értékeket nem érdemes használniConfigureDepthVideoStream
, a HoloLens 2 való kapcsolat létrehozása előtt meg kell hívni. A legjobb hely közvetlenül a távoli környezet létrehozása után található. A DepthBufferStreamResolution lehetséges értékei a következők:
- Full_Resolution
- Half_Resolution
- Quarter_Resolution
- Letiltva ( a 2.1.3-es verzióval lett hozzáadva, és ha nincs használatban további mélységi videóstream)
Ne feledje, hogy a teljes felbontású mélységi puffer használata hatással van a sávszélesség-követelményekre is, és figyelembe kell venni a számára megadott CreateRemoteContext
maximális sávszélesség-értéket.
A felbontás konfigurálása mellett mélységi puffert is véglegesítenie kell a HolographicCameraRenderingParameters.CommitDirect3D11DepthBuffer használatával.
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);
}
});
}
});
}
Annak ellenőrzéséhez, hogy a mélységi újraprojection megfelelően működik-e HoloLens 2, engedélyezheti a mélységi vizualizációt az eszközportálon. A részletekért lásd: A mélység helyesen van beállítva .
Nem kötelező: Egyéni adatcsatornák
Az egyéni adatcsatornák segítségével felhasználói adatokat küldhet a már létrehozott újrakapcsolódási kapcsolaton keresztül. További információ: Egyéni adatcsatornák.
Nem kötelező: A rendszerszinkronizálás koordinálása
A 2.7.0-s verziótól kezdve a koordinátarendszer-szinkronizálás használható a térbeli adatok a lejátszó és a távoli alkalmazás közötti igazítására. További információ: A rendszerszinkronizálás koordinálása holografikus újraegyenlítéssel – áttekintés.
Lásd még:
- Holografikus átnevezés áttekintése
- Egyéni Holographic Remoting lejátszóalkalmazás írása
- Egyéni holografikus adatcsatornák
- Biztonságos kapcsolat létrehozása a Holographic Remoting használatával
- Holografikus átnevezés hibaelhárítása és korlátozásai
- Holographic Remoting szoftverlicenc-feltételek
- A Microsoft adatvédelmi nyilatkozata