### MediaCodecDecoderRenderer Initialization and Setup Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Initialize and configure the hardware video decoder renderer. Set the render target surface and retrieve decoder capabilities. ```java // Create the video decoder renderer MediaCodecDecoderRenderer videoRenderer = new MediaCodecDecoderRenderer( activity, prefs, // PreferenceConfiguration crashListener, // Handle decoder crashes 0, // Consecutive crash count isMeteredNetwork, requestedHdr, glRenderer, // OpenGL renderer string for device detection perfListener // Performance overlay listener ); // Set the render target surface videoRenderer.setRenderTarget(surfaceHolder); // Get decoder capabilities for the connection int capabilities = videoRenderer.getCapabilities(); ``` -------------------------------- ### Build Moonlight Android Application with Gradle Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Commands for cloning the repository, initializing submodules, setting up NDK path, and building debug or release APKs. Includes instructions for installing the built APK on a connected device. ```bash # Clone the repository git clone https://github.com/moonlight-stream/moonlight-android.git cd moonlight-android ``` ```bash # Initialize submodules (moonlight-common-c) git submodule update --init --recursive ``` ```bash # Create local.properties with NDK path echo "ndk.dir=/path/to/android-ndk" > local.properties ``` ```bash # Build debug APK ./gradlew assembleDebug ``` ```bash # Build release APK ./gradlew assembleRelease ``` ```bash # Build specific flavor ./gradlew assembleNonRootDebug # Standard build ./gradlew assembleRootDebug # Root build (for pre-Android O devices) ``` ```bash # Install on connected device ./gradlew installDebug ``` -------------------------------- ### Create and Start Streaming Connection Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Initiates a streaming connection to a host PC. Requires server details, unique ID, certificate, stream configuration, and crypto provider. Implements a listener for connection events. ```java ComputerDetails.AddressTuple serverAddress = new ComputerDetails.AddressTuple("192.168.1.100", 47989); String uniqueId = "0123456789ABCDEF"; X509Certificate serverCert = /* previously obtained from pairing */; // Configure the stream settings StreamConfiguration config = new StreamConfiguration.Builder() .setResolution(1920, 1080) .setRefreshRate(60) .setBitrate(20000) // 20 Mbps .setApp(new NvApp("Steam", 1234567890)) .setRemoteConfiguration(StreamConfiguration.STREAM_CFG_AUTO) .setAudioConfiguration(MoonBridge.AUDIO_CONFIGURATION_STEREO) .setSupportedVideoFormats(MoonBridge.VIDEO_FORMAT_H264 | MoonBridge.VIDEO_FORMAT_H265) .setMaxPacketSize(1024) .build(); // Create the connection NvConnection connection = new NvConnection( context, serverAddress, 47984, // HTTPS port uniqueId, config, cryptoProvider, serverCert ); // Start streaming with renderers and listener connection.start(audioRenderer, videoDecoderRenderer, new NvConnectionListener() { @Override public void stageStarting(String stage) { Log.d("Moonlight", "Starting: " + stage); } @Override public void stageComplete(String stage) { Log.d("Moonlight", "Completed: " + stage); } @Override public void stageFailed(String stage, int portFlags, int errorCode) { Log.e("Moonlight", "Failed at " + stage + ": error " + errorCode); } @Override public void connectionStarted() { Log.d("Moonlight", "Stream started successfully"); } @Override public void connectionTerminated(int errorCode) { Log.d("Moonlight", "Stream ended: " + errorCode); } @Override public void rumble(short controllerNumber, short lowFreqMotor, short highFreqMotor) { // Handle controller rumble feedback } @Override public void setHdrMode(boolean enabled, byte[] hdrMetadata) { // Handle HDR mode changes } }); // Stop the connection when done connection.stop(); ``` -------------------------------- ### VideoDecoderRenderer Interface Implementation Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Implement the VideoDecoderRenderer interface for hardware-accelerated video decoding. Handle setup, frame submission, and resource management. ```java // VideoDecoderRenderer interface implementation (called by MoonBridge) public class MediaCodecDecoderRenderer extends VideoDecoderRenderer { @Override public int setup(int videoFormat, int width, int height, int redrawRate) { // Initialize MediaCodec decoder // videoFormat: MoonBridge.VIDEO_FORMAT_H264, etc. // Returns: 0 on success, negative on failure } @Override public void start() { // Start decoder output processing } @Override public int submitDecodeUnit(byte[] data, int length, int type, int frameNumber, int frameType, char hostLatency, long receiveTimeMs, long enqueueTimeMs) { // Submit encoded frame data to decoder // type: BUFFER_TYPE_PICDATA, BUFFER_TYPE_SPS, BUFFER_TYPE_PPS, BUFFER_TYPE_VPS // Returns: DR_OK or DR_NEED_IDR (request keyframe) } @Override public void stop() { // Stop decoder } @Override public void cleanup() { // Release decoder resources } @Override public int getCapabilities() { // Return capability flags for the decoder } } ``` -------------------------------- ### Initialize and Use ControllerHandler in Android Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Demonstrates how to create a ControllerHandler instance and process various Android input events like key presses, motion events, rumble feedback, and sensor requests. Ensure the activity, connection, gestures, and preferences are correctly initialized. ```java ControllerHandler controllerHandler = new ControllerHandler( activity, nvConnection, gameGestures, // For handling special gestures prefConfig // Preference configuration ); ``` ```java // Process Android input events @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (ControllerHandler.isGameControllerDevice(event.getDevice())) { return controllerHandler.handleButtonDown(event); } return false; } ``` ```java @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (ControllerHandler.isGameControllerDevice(event.getDevice())) { return controllerHandler.handleButtonUp(event); } return false; } ``` ```java @Override public boolean onGenericMotionEvent(MotionEvent event) { return controllerHandler.handleMotionEvent(event); } ``` ```java // Get initial controller count for streaming configuration short attachedControllerMask = ControllerHandler.getAttachedControllerMask(context); ``` ```java // Handle rumble feedback from the host controllerHandler.handleRumble((short) 0, (short) 32767, (short) 16383); ``` ```java // Handle trigger rumble (Xbox controllers) controllerHandler.handleRumbleTriggers((short) 0, (short) 8000, (short) 8000); ``` ```java // Handle motion sensor requests controllerHandler.handleSetMotionEventState( (short) 0, // Controller number MoonBridge.LI_MOTION_TYPE_GYRO, // Motion type (short) 100 // Report rate Hz ); ``` ```java // Handle LED color requests (DualSense, etc.) controllerHandler.handleSetControllerLED((short) 0, (byte) 255, (byte) 0, (byte) 0); // Red ``` ```java // On-screen controller state reporting controllerHandler.reportOscState( ControllerPacket.A_FLAG, // Button flags (short) 0, (short) 0, // Left stick (short) 0, (short) 0, // Right stick (byte) 0, (byte) 0 // Triggers ); ``` ```java // Lifecycle management controllerHandler.enableSensors(); // When app resumes controllerHandler.disableSensors(); // When app pauses controllerHandler.stop(); // When streaming stops controllerHandler.destroy(); // When activity is destroyed ``` -------------------------------- ### Configure High-Quality 4K HDR Stream Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Builds a StreamConfiguration for a 4K HDR stream, optimizing for LAN performance with high bitrate and specific audio/video formats. Includes options for enabling optimizations and local audio playback. ```java // Configure a high-quality 4K HDR stream StreamConfiguration config = new StreamConfiguration.Builder() .setApp(new NvApp("Steam", 1234567890)) .setResolution(3840, 2160) // 4K resolution .setRefreshRate(60) .setLaunchRefreshRate(60) .setBitrate(80000) // 80 Mbps for 4K .setMaxPacketSize(1392) // Larger packets for LAN .setRemoteConfiguration(StreamConfiguration.STREAM_CFG_LOCAL) // LAN streaming .setAudioConfiguration(MoonBridge.AUDIO_CONFIGURATION_71_SURROUND) .setSupportedVideoFormats( MoonBridge.VIDEO_FORMAT_H265 | MoonBridge.VIDEO_FORMAT_H265_MAIN10 // Enable HDR ) .setColorSpace(MoonBridge.COLORSPACE_REC_2020) .setColorRange(MoonBridge.COLOR_RANGE_LIMITED) .setEnableSops(true) // Enable streaming optimizations .enableLocalAudioPlayback(false) .setAttachedGamepadMaskByCount(1) .setPersistGamepadsAfterDisconnect(false) .build(); // Get configuration values int width = config.getWidth(); // 3840 int height = config.getHeight(); // 2160 int fps = config.getRefreshRate(); // 60 int bitrate = config.getBitrate(); // 80000 ``` -------------------------------- ### NvHTTP Server Communication API Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Use NvHTTP to communicate with the host PC for server discovery, pairing, app lists, and game launching. Requires server address, port, unique ID, certificate, and crypto provider. ```java ComputerDetails.AddressTuple address = new ComputerDetails.AddressTuple("192.168.1.100", 47989); NvHTTP http = new NvHTTP(address, 47984, uniqueId, serverCert, cryptoProvider); ``` ```java String serverInfo = http.getServerInfo(true); // true = likely online ComputerDetails details = http.getComputerDetails(serverInfo); ``` ```java String hostname = details.name; // "GAMING-PC" String uuid = details.uuid; // Server's unique identifier String macAddress = details.macAddress; // For Wake-on-LAN boolean isPaired = details.pairState == PairingManager.PairState.PAIRED; boolean isNvidia = details.nvidiaServer; // true for GFE, false for Sunshine ``` ```java String serverVersion = http.getServerVersion(serverInfo); // "7.1.431.0" boolean supports4K = http.supports4K(serverInfo); long codecSupport = http.getServerCodecModeSupport(serverInfo); String gpuType = http.getGpuType(serverInfo); // "GeForce RTX 4090" ``` ```java LinkedList apps = http.getAppList(); for (NvApp app : apps) { Log.d("Moonlight", "App: " + app.getAppName() + " (ID: " + app.getAppId() + ")"); if (app.isHdrSupported()) { Log.d("Moonlight", " - HDR supported"); } } ``` ```java NvApp steam = http.getAppByName("Steam"); NvApp appById = http.getAppById(1234567890); ``` ```java InputStream boxArt = http.getBoxArt(steam); ``` ```java int currentGameId = http.getCurrentGame(serverInfo); if (currentGameId != 0) { Log.d("Moonlight", "Currently running game ID: " + currentGameId); } ``` ```java boolean success = http.quitApp(); ``` -------------------------------- ### Send Controller Arrival Event Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Notify the host about a controller connecting, specifying its number, type, supported buttons, and capabilities. This is crucial for the host to recognize and configure the controller. ```java // Controller arrival event (when controller connects) connection.sendControllerArrivalEvent( (byte) 0, // Controller number (short) 0x01, // Active gamepad mask MoonBridge.LI_CTYPE_XBOX, // Controller type ControllerPacket.A_FLAG | ControllerPacket.B_FLAG | /*...*/ 0, // Supported buttons (short) (MoonBridge.LI_CCAP_RUMBLE | MoonBridge.LI_CCAP_ANALOG_TRIGGERS) // Capabilities ); ``` -------------------------------- ### PairingManager Device Pairing Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Use PairingManager for secure client-host pairing via PIN. Generate a PIN, initiate pairing with the server info and PIN, and handle the pairing result. Check and unpair status later. ```java PairingManager pm = http.getPairingManager(); ``` ```java String pin = PairingManager.generatePinString(); // e.g., "1234" Log.d("Moonlight", "Enter this PIN on your PC: " + pin); ``` ```java String serverInfo = http.getServerInfo(true); PairingManager.PairState result = pm.pair(serverInfo, pin); ``` ```java switch (result) { case PAIRED: // Success! Save the server certificate for future connections X509Certificate serverCert = pm.getPairedCert(); Log.d("Moonlight", "Successfully paired with server"); break; case PIN_WRONG: Log.e("Moonlight", "Incorrect PIN entered"); break; case ALREADY_IN_PROGRESS: Log.e("Moonlight", "Another device is already pairing"); break; case FAILED: Log.e("Moonlight", "Pairing failed"); break; } ``` ```java PairingManager.PairState state = http.getPairState(); if (state == PairingManager.PairState.PAIRED) { Log.d("Moonlight", "Device is paired"); } ``` ```java http.unpair(); ``` -------------------------------- ### Send Keyboard Input Event Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Send a single keyboard input event by specifying the virtual key code, action (down/up), modifier keys, and flags. Ensure the virtual key code is correct for the desired key. ```java // Keyboard input connection.sendKeyboardInput( (short) 0x41, // Virtual key code (A key) (byte) 0x01, // Key down (byte) 0x00, // No modifiers (byte) 0x00 // Flags ); ``` -------------------------------- ### Send Controller Input Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Send controller input data including button states, trigger values, and analog stick positions. Ensure correct controller number and active mask are used. ```java // Controller input short controllerNumber = 0; short activeGamepadMask = 0x01; // Controller 1 active int buttonFlags = ControllerPacket.A_FLAG | ControllerPacket.LB_FLAG; byte leftTrigger = (byte) 0xFF; // Fully pressed byte rightTrigger = (byte) 0x00; // Not pressed short leftStickX = (short) 16384; // Half right short leftStickY = (short) 0; short rightStickX = (short) 0; short rightStickY = (short) -32767; // Full up connection.sendControllerInput( controllerNumber, activeGamepadMask, buttonFlags, leftTrigger, rightTrigger, leftStickX, leftStickY, rightStickX, rightStickY ); ``` -------------------------------- ### MoonBridge JNI Interface Constants and Utilities Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Utilize MoonBridge constants for video and audio formats, controller types, and network diagnostics. Check HDR support and network conditions. ```java // Video format constants int h264 = MoonBridge.VIDEO_FORMAT_H264; int hevc = MoonBridge.VIDEO_FORMAT_H265; int hevcHdr = MoonBridge.VIDEO_FORMAT_H265_MAIN10; int av1 = MoonBridge.VIDEO_FORMAT_AV1_MAIN8; int av1Hdr = MoonBridge.VIDEO_FORMAT_AV1_MAIN10; // Check for HDR support int supportedFormats = MoonBridge.VIDEO_FORMAT_H264 | MoonBridge.VIDEO_FORMAT_H265_MAIN10; boolean supportsHdr = (supportedFormats & MoonBridge.VIDEO_FORMAT_MASK_10BIT) != 0; // Audio configuration MoonBridge.AudioConfiguration stereo = MoonBridge.AUDIO_CONFIGURATION_STEREO; MoonBridge.AudioConfiguration surround51 = MoonBridge.AUDIO_CONFIGURATION_51_SURROUND; MoonBridge.AudioConfiguration surround71 = MoonBridge.AUDIO_CONFIGURATION_71_SURROUND; // Get audio configuration properties int channels = stereo.channelCount; // 2 int channelMask = stereo.channelMask; // 0x3 // Video decoder capabilities for hardware acceleration int capabilities = MoonBridge.CAPABILITY_DIRECT_SUBMIT | MoonBridge.CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC | MoonBridge.CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC | MoonBridge.CAPABILITY_SLICES_PER_FRAME((byte) 4); // Controller type detection byte controllerType = MoonBridge.guessControllerType(0x045e, 0x0b12); // Xbox vendor/product // Returns: MoonBridge.LI_CTYPE_XBOX, LI_CTYPE_PS, LI_CTYPE_NINTENDO, or LI_CTYPE_UNKNOWN boolean hasPaddles = MoonBridge.guessControllerHasPaddles(0x045e, 0x0b12); boolean hasShareButton = MoonBridge.guessControllerHasShareButton(0x045e, 0x0b12); // Network diagnostics long rttInfo = MoonBridge.getEstimatedRttInfo(); int rtt = (int) (rttInfo >> 32); // Round-trip time in ms int rttVariance = (int) (rttInfo & 0xFFFFFFFF); // RTT variance // Connection quality monitoring int pendingAudioMs = MoonBridge.getPendingAudioDuration(); int pendingVideoFrames = MoonBridge.getPendingVideoFrames(); // External address discovery via STUN String externalIp = MoonBridge.findExternalAddressIP4("stun.l.google.com", 19302); // Port testing for connectivity int testResult = MoonBridge.testClientConnectivity( "test.moonlight-stream.org", 47989, MoonBridge.ML_PORT_FLAG_ALL ); if (testResult == MoonBridge.ML_TEST_RESULT_INCONCLUSIVE) { Log.w("Moonlight", "Port test inconclusive"); } // Error code diagnostics int portFlags = MoonBridge.getPortFlagsFromTerminationErrorCode(errorCode); String portList = MoonBridge.stringifyPortFlags(portFlags, ", "); // Example output: "TCP 47984, TCP 47989, UDP 47998" ``` -------------------------------- ### Send Mouse Input Events Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Use these methods to send relative or absolute mouse movements, button presses/releases, and scroll events. Ensure correct button and scroll values are used. ```java // Mouse input connection.sendMouseMove((short) 10, (short) -5); // Relative movement connection.sendMousePosition((short) 960, (short) 540, (short) 1920, (short) 1080); // Absolute position connection.sendMouseButtonDown(MouseButtonPacket.BUTTON_LEFT); connection.sendMouseButtonUp(MouseButtonPacket.BUTTON_LEFT); connection.sendMouseScroll((byte) 1); // Scroll up connection.sendMouseHScroll((byte) -1); // Scroll left connection.sendMouseHighResScroll((short) 120); // High-resolution scroll ``` -------------------------------- ### Send Pen/Stylus Input Event Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Send pen or stylus input events, including tool type, button states, position, pressure, contact area, rotation, and tilt. Ensure the correct tool type and event type are used. ```java // Pen/stylus input connection.sendPenEvent( MoonBridge.LI_TOUCH_EVENT_DOWN, MoonBridge.LI_TOOL_TYPE_PEN, (byte) 0, // No pen buttons pressed 0.5f, 0.5f, // Position 0.8f, // Pressure 2.0f, 1.0f, // Contact area (short) 45, // Rotation (byte) 30 // Tilt angle ); ``` -------------------------------- ### Send Touch Input Event Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Send touch events for touchscreen support, specifying event type, pointer ID, position, pressure, and contact area. Position and area are normalized to a 0.0-1.0 range. ```java // Touch input for touchscreen support int result = connection.sendTouchEvent( MoonBridge.LI_TOUCH_EVENT_DOWN, // Event type 0, // Pointer ID 0.5f, // X position (0.0-1.0) 0.5f, // Y position (0.0-1.0) 1.0f, // Pressure 50.0f, // Contact area major 50.0f, // Contact area minor (short) 0 // Rotation ); ``` -------------------------------- ### Send UTF-8 Text Input Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Send a string of UTF-8 encoded text to the streaming session. This is useful for text input fields. ```java // UTF-8 text input connection.sendUtf8Text("Hello World!"); ``` -------------------------------- ### Send Controller Battery Status Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Report the battery status of a controller, including its discharge state and remaining percentage. This allows the host to monitor battery levels. ```java // Controller battery status connection.sendControllerBatteryEvent( (byte) 0, // Controller number MoonBridge.LI_BATTERY_STATE_DISCHARGING, (byte) 75 // 75% battery ); ``` -------------------------------- ### Send Controller Motion Sensor Data Source: https://context7.com/moonlight-stream/moonlight-android/llms.txt Transmit motion sensor data (gyroscope or accelerometer) from a controller. Specify the controller number, motion type, and the X, Y, Z values for the sensor readings. ```java // Controller motion sensors (gyro/accelerometer) connection.sendControllerMotionEvent( (byte) 0, // Controller number MoonBridge.LI_MOTION_TYPE_GYRO, // Motion type 0.5f, -0.2f, 0.1f // X, Y, Z angular velocity (deg/s) ); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.