Compare commits

..

34 Commits

Author SHA1 Message Date
Cameron Gutman 077cb2103d Version 10.1 2022-05-18 22:44:46 -05:00
Cameron Gutman cdeda011a4 Temporarily disable in-app links until they are translated 2022-05-18 22:40:47 -05:00
Cameron Gutman 894c146988 Fix JAVA_HOME path on VS2022 CI image 2022-05-18 00:57:05 -05:00
Cameron Gutman 61cc9e151f Use newer AppVeyor machine image 2022-05-18 00:38:47 -05:00
Cameron Gutman cfe4c9ff21 Target Android 12L 2022-05-17 17:16:28 -05:00
Cameron Gutman d4bd29b320 Properly deal with battery saver mode in capped FPS mode 2022-05-17 00:14:55 -05:00
Cameron Gutman 7f2f2056c3 Add in-app privacy policy link to comply with Google Play policies
Also added Setup Guide and Troubleshooting Guide links too.
2022-05-15 15:56:19 -05:00
Cameron Gutman 4dd3b2cfb7 Tweak capped FPS option text 2022-05-14 23:33:43 -05:00
Cameron Gutman 2e62ad0f00 Merge remote-tracking branch 'origin/weblate' 2022-05-14 23:31:51 -05:00
Cameron Gutman 41ef292b82 Fix frame rate cap not taking effect with the unlock FPS option enabled 2022-05-14 21:19:51 -05:00
Cameron Gutman aa60671c88 Return the selected refresh rate now that the capped FPS mode is not default 2022-05-14 20:53:42 -05:00
Cameron Gutman f1ccba39e8 Don't raise refresh rate above stream FPS except in min latency mode 2022-05-14 20:53:07 -05:00
Cameron Gutman 226e580a30 Prevent microstutter in balanced mode when streaming at 60 FPS on a 120 Hz display 2022-05-14 20:08:41 -05:00
Cameron Gutman 6f8e719200 Update AGP 2022-05-14 18:25:48 -05:00
Cameron Gutman c127af1e05 Rewrite polling logic to avoid needing to poll using a separate socket first 2022-05-14 18:14:37 -05:00
Wen-haur Chiu 648904cc69 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (211 of 211 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/zh_Hant/
2022-05-11 19:13:59 +02:00
Cameron Gutman dc85ddb3f9 Reintroduce option of using old frame pacing algorithm using capped FPS 2022-05-08 15:20:08 -05:00
Cameron Gutman 23a7d8555f Avoid activity restarts in StreamSettings and AddComputerManually
We would ideally save and restore state, but this is fine for these specific
transient user activities.

Fixes #1052
Fixes #1055
2022-05-08 14:55:47 -05:00
Cameron Gutman bc9e250d34 Merge remote-tracking branch 'origin/weblate' 2022-05-08 14:40:07 -05:00
Cameron Gutman 2203186527 Remove extra ViewGroup between OSC and StreamView
This allows touch events to be properly split
2022-05-08 14:39:32 -05:00
DankXylese 53d3d9ecb8 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (210 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/uk/
2022-04-28 21:13:07 +02:00
Cameron Gutman de549f67a1 Update README 2022-04-05 19:51:44 -05:00
Jorys Paulin 755c41481a Translated using Weblate (French)
Currently translated at 100.0% (210 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/fr/
2022-04-04 10:12:11 +02:00
Dominik Chrástecký aebc2126bc Added translation using Weblate (Czech) 2022-04-03 19:50:26 +02:00
Wen-haur Chiu f43547fb31 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (210 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/zh_Hant/
2022-03-25 18:11:43 +01:00
CorteX 398e4df7cf Translated using Weblate (Chinese (Simplified))
Currently translated at 98.0% (206 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/zh_Hans/
2022-03-23 06:58:35 +01:00
reloxx13 ff68efc3f5 Translated using Weblate (German)
Currently translated at 100.0% (210 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/de/
2022-03-21 09:59:13 +01:00
Caio Gabriel 8ba2f51bda Translated using Weblate (Portuguese)
Currently translated at 9.0% (19 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/pt/
2022-03-19 22:58:22 +01:00
Caio Gabriel 87b79b278b Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (210 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/pt_BR/
2022-03-19 22:58:21 +01:00
Caio Gabriel 121e3ea9be Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (210 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/pt_BR/
2022-03-18 16:45:57 +01:00
Caio Gabriel ec6ed79ee1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (210 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/pt_BR/
2022-03-18 03:47:44 +01:00
Caio Gabriel ca125826a7 Translated using Weblate (Portuguese)
Currently translated at 8.5% (18 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/pt/
2022-03-17 22:58:19 +01:00
Cameron Gutman dd0aecf108 Update BouncyCastle 2022-03-15 22:16:41 -05:00
Wen-haur Chiu ef5cb2f0cd Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (210 of 210 strings)

Translation: Moonlight Game Streaming/moonlight-android
Translate-URL: https://hosted.weblate.org/projects/moonlight/moonlight-android/zh_Hant/
2022-03-09 15:58:49 +01:00
27 changed files with 595 additions and 184 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/232a8tadrrn8jv0k/branch/master?svg=true)](https://ci.appveyor.com/project/cgutman/moonlight-android/branch/master)
[![Translation Status](https://hosted.weblate.org/widgets/moonlight/-/moonlight-android/svg-badge.svg)](https://hosted.weblate.org/projects/moonlight/moonlight-android/)
[Moonlight for Android](https://moonlight-stream.org) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield.
[Moonlight for Android](https://moonlight-stream.org) is an open source client for NVIDIA GameStream, as used by the NVIDIA Shield.
Moonlight for Android will allow you to stream your full collection of games from your Windows PC to your Android device,
whether in your own home or over the internet.
+6 -6
View File
@@ -3,14 +3,14 @@ apply plugin: 'com.android.application'
android {
ndkVersion "23.1.7779620"
compileSdkVersion 31
compileSdkVersion 32
defaultConfig {
minSdkVersion 16
targetSdkVersion 31
targetSdkVersion 32
versionName "10.0"
versionCode = 272
versionName "10.1"
versionCode = 273
}
flavorDimensions "root"
@@ -118,8 +118,8 @@ android {
}
dependencies {
implementation 'org.bouncycastle:bcprov-jdk15on:1.69'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.69'
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
implementation 'org.jcodec:jcodec:0.2.3'
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
implementation 'com.squareup.okio:okio:1.17.5'
+2
View File
@@ -99,6 +99,7 @@
<activity
android:name=".preferences.StreamSettings"
android:resizeableActivity="true"
android:configChanges="mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
android:label="Streaming Settings">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
@@ -108,6 +109,7 @@
android:name=".preferences.AddComputerManually"
android:resizeableActivity="true"
android:windowSoftInputMode="stateVisible"
android:configChanges="mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
android:label="Add Computer Manually">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
+55 -8
View File
@@ -389,6 +389,28 @@ public class Game extends Activity implements SurfaceHolder.Callback,
float displayRefreshRate = prepareDisplayForRendering();
LimeLog.info("Display refresh rate: "+displayRefreshRate);
// If the user requested frame pacing using a capped FPS, we will need to change our
// desired FPS setting here in accordance with the active display refresh rate.
int roundedRefreshRate = Math.round(displayRefreshRate);
int chosenFrameRate = prefConfig.fps;
if (prefConfig.framePacing == PreferenceConfiguration.FRAME_PACING_CAP_FPS) {
if (prefConfig.fps >= roundedRefreshRate) {
if (prefConfig.fps > roundedRefreshRate + 3) {
// Use frame drops when rendering above the screen frame rate
prefConfig.framePacing = PreferenceConfiguration.FRAME_PACING_BALANCED;
LimeLog.info("Using drop mode for FPS > Hz");
} else if (roundedRefreshRate <= 49) {
// Let's avoid clearly bogus refresh rates and fall back to legacy rendering
prefConfig.framePacing = PreferenceConfiguration.FRAME_PACING_BALANCED;
LimeLog.info("Bogus refresh rate: " + roundedRefreshRate);
}
else {
chosenFrameRate = roundedRefreshRate - 1;
LimeLog.info("Adjusting FPS target for screen to " + chosenFrameRate);
}
}
}
boolean vpnActive = NetHelper.isActiveNetworkVpn(this);
if (vpnActive) {
LimeLog.info("Detected active network is a VPN");
@@ -397,7 +419,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
StreamConfiguration config = new StreamConfiguration.Builder()
.setResolution(prefConfig.width, prefConfig.height)
.setLaunchRefreshRate(prefConfig.fps)
.setRefreshRate(prefConfig.fps)
.setRefreshRate(chosenFrameRate)
.setApp(new NvApp(appName != null ? appName : "app", appId, appSupportsHdr))
.setBitrate(prefConfig.bitrate)
.setEnableSops(prefConfig.enableSops)
@@ -573,6 +595,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
inputCaptureProvider.onWindowFocusChanged(hasFocus);
}
private boolean isRefreshRateEqualMatch(float refreshRate) {
return refreshRate >= prefConfig.fps &&
refreshRate <= prefConfig.fps + 3;
}
private boolean isRefreshRateGoodMatch(float refreshRate) {
return refreshRate >= prefConfig.fps &&
Math.round(refreshRate) % prefConfig.fps <= 3;
@@ -608,6 +635,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
Display.Mode bestMode = display.getMode();
boolean isNativeResolutionStream = PreferenceConfiguration.isNativeResolution(prefConfig.width, prefConfig.height);
boolean refreshRateIsGood = isRefreshRateGoodMatch(bestMode.getRefreshRate());
boolean refreshRateIsEqual = isRefreshRateEqualMatch(bestMode.getRefreshRate());
for (Display.Mode candidate : display.getSupportedModes()) {
boolean refreshRateReduced = candidate.getRefreshRate() < bestMode.getRefreshRate();
boolean resolutionReduced = candidate.getPhysicalWidth() < bestMode.getPhysicalWidth() ||
@@ -639,12 +667,30 @@ public class Game extends Activity implements SurfaceHolder.Callback,
continue;
}
if (refreshRateIsGood) {
// We have a good matching refresh rate, so we're looking for equal or greater
// that is also a good matching refresh rate for our stream frame rate.
if (refreshRateReduced || !isRefreshRateGoodMatch(candidate.getRefreshRate())) {
if (prefConfig.framePacing != PreferenceConfiguration.FRAME_PACING_MIN_LATENCY &&
refreshRateIsEqual && !isRefreshRateEqualMatch(candidate.getRefreshRate())) {
// If we had an equal refresh rate and this one is not, skip it. In min latency
// mode, we want to always prefer the highest frame rate even though it may cause
// microstuttering.
continue;
}
else if (refreshRateIsGood) {
// We've already got a good match, so if this one isn't also good, it's not
// worth considering at all.
if (!isRefreshRateGoodMatch(candidate.getRefreshRate())) {
continue;
}
// We don't want ever reduce our refresh rate unless we found an exact
// match and we're not in min latency mode.
if (refreshRateReduced) {
if (prefConfig.framePacing == PreferenceConfiguration.FRAME_PACING_MIN_LATENCY) {
continue;
}
else if (!isRefreshRateEqualMatch(candidate.getRefreshRate())) {
continue;
}
}
}
else if (!isRefreshRateGoodMatch(candidate.getRefreshRate())) {
// We didn't have a good match and this match isn't good either, so just don't
@@ -661,6 +707,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
bestMode = candidate;
refreshRateIsGood = isRefreshRateGoodMatch(candidate.getRefreshRate());
refreshRateIsEqual = isRefreshRateEqualMatch(candidate.getRefreshRate());
}
LimeLog.info("Selected display mode: "+bestMode.getPhysicalWidth()+"x"+
bestMode.getPhysicalHeight()+"x"+bestMode.getRefreshRate());
@@ -741,9 +788,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
return displayRefreshRate;
}
else {
// Use the actual refresh rate of the display, since the preferred refresh rate or mode
// may not actually be applied (ex: Pixel 4 with Smooth Display disabled).
return getWindowManager().getDefaultDisplay().getRefreshRate();
// Use the lower of the current refresh rate and the selected refresh rate.
// The preferred refresh rate may not actually be applied (ex: Battery Saver mode).
return Math.min(getWindowManager().getDefaultDisplay().getRefreshRate(), displayRefreshRate);
}
}
@@ -9,12 +9,11 @@ import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;
import com.limelight.LimeLog;
import com.limelight.R;
import com.limelight.binding.input.ControllerHandler;
import com.limelight.nvstream.NvConnection;
import java.util.ArrayList;
import java.util.List;
@@ -40,11 +39,10 @@ public class VirtualController {
private static final boolean _PRINT_DEBUG_INFORMATION = false;
private ControllerHandler controllerHandler;
private Context context = null;
private final ControllerHandler controllerHandler;
private final Context context;
private FrameLayout frame_layout = null;
private RelativeLayout relative_layout = null;
private Timer retransmitTimer;
@@ -60,10 +58,6 @@ public class VirtualController {
this.frame_layout = layout;
this.context = context;
relative_layout = new RelativeLayout(context);
frame_layout.addView(relative_layout);
buttonConfigure = new Button(context);
buttonConfigure.setAlpha(0.25f);
buttonConfigure.setFocusable(false);
@@ -87,7 +81,7 @@ public class VirtualController {
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
relative_layout.invalidate();
buttonConfigure.invalidate();
for (VirtualControllerElement element : elements) {
element.invalidate();
@@ -99,11 +93,20 @@ public class VirtualController {
public void hide() {
retransmitTimer.cancel();
relative_layout.setVisibility(View.INVISIBLE);
for (VirtualControllerElement element : elements) {
element.setVisibility(View.INVISIBLE);
}
buttonConfigure.setVisibility(View.INVISIBLE);
}
public void show() {
relative_layout.setVisibility(View.VISIBLE);
for (VirtualControllerElement element : elements) {
element.setVisibility(View.VISIBLE);
}
buttonConfigure.setVisibility(View.VISIBLE);
// HACK: GFE sometimes discards gamepad packets when they are received
// very shortly after another. This can be critical if an axis zeroing packet
@@ -120,9 +123,11 @@ public class VirtualController {
public void removeElements() {
for (VirtualControllerElement element : elements) {
relative_layout.removeView(element);
frame_layout.removeView(element);
}
elements.clear();
frame_layout.removeView(buttonConfigure);
}
public void setOpacity(int opacity) {
@@ -134,10 +139,10 @@ public class VirtualController {
public void addElement(VirtualControllerElement element, int x, int y, int width, int height) {
elements.add(element);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, height);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(width, height);
layoutParams.setMargins(x, y, 0, 0);
relative_layout.addView(element, layoutParams);
frame_layout.addView(element, layoutParams);
}
public List<VirtualControllerElement> getElements() {
@@ -146,23 +151,20 @@ public class VirtualController {
private static final void _DBG(String text) {
if (_PRINT_DEBUG_INFORMATION) {
System.out.println("VirtualController: " + text);
LimeLog.info("VirtualController: " + text);
}
}
public void refreshLayout() {
relative_layout.removeAllViews();
removeElements();
DisplayMetrics screen = context.getResources().getDisplayMetrics();
int buttonSize = (int)(screen.heightPixels*0.06f);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(buttonSize, buttonSize);
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(buttonSize, buttonSize);
params.leftMargin = 15;
params.topMargin = 15;
relative_layout.addView(buttonConfigure, params);
frame_layout.addView(buttonConfigure, params);
// Start with the default layout
VirtualControllerConfigurationLoader.createDefaultLayout(this, context);
@@ -12,7 +12,7 @@ import android.graphics.Paint;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.FrameLayout;
import org.json.JSONException;
import org.json.JSONObject;
@@ -72,7 +72,7 @@ public abstract class VirtualControllerElement extends View {
int newPos_x = (int) getX() + x - pressed_x;
int newPos_y = (int) getY() + y - pressed_y;
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin = newPos_x > 0 ? newPos_x : 0;
layoutParams.topMargin = newPos_y > 0 ? newPos_y : 0;
@@ -83,7 +83,7 @@ public abstract class VirtualControllerElement extends View {
}
protected void resizeElement(int pressed_x, int pressed_y, int width, int height) {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
int newHeight = height + (startSize_y - pressed_y);
int newWidth = width + (startSize_x - pressed_x);
@@ -316,7 +316,7 @@ public abstract class VirtualControllerElement extends View {
public JSONObject getConfiguration() throws JSONException {
JSONObject configuration = new JSONObject();
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
configuration.put("LEFT", layoutParams.leftMargin);
configuration.put("TOP", layoutParams.topMargin);
@@ -327,7 +327,7 @@ public abstract class VirtualControllerElement extends View {
}
public void loadConfiguration(JSONObject configuration) throws JSONException {
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
layoutParams.leftMargin = configuration.getInt("LEFT");
layoutParams.topMargin = configuration.getInt("TOP");
@@ -86,6 +86,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
private LinkedBlockingQueue<Integer> outputBufferQueue = new LinkedBlockingQueue<>();
private static final int OUTPUT_BUFFER_QUEUE_LIMIT = 2;
private long lastRenderedFrameTimeNanos;
private int numSpsIn;
private int numPpsIn;
@@ -419,21 +420,28 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
return;
}
// Render up to one frame when in frame pacing mode.
//
// NB: Since the queue limit is 2, we won't starve the decoder of output buffers
// by holding onto them for too long. This also ensures we will have that 1 extra
// frame of buffer to smooth over network/rendering jitter.
Integer nextOutputBuffer = outputBufferQueue.poll();
if (nextOutputBuffer != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
videoDecoder.releaseOutputBuffer(nextOutputBuffer, frameTimeNanos);
}
else {
videoDecoder.releaseOutputBuffer(nextOutputBuffer, true);
}
// Don't render unless a new frame is due. This prevents microstutter when streaming
// at a frame rate that doesn't match the display (such as 60 FPS on 120 Hz).
long actualFrameTimeDeltaNs = frameTimeNanos - lastRenderedFrameTimeNanos;
long expectedFrameTimeDeltaNs = 800000000 / refreshRate; // within 80% of the next frame
if (actualFrameTimeDeltaNs >= expectedFrameTimeDeltaNs) {
// Render up to one frame when in frame pacing mode.
//
// NB: Since the queue limit is 2, we won't starve the decoder of output buffers
// by holding onto them for too long. This also ensures we will have that 1 extra
// frame of buffer to smooth over network/rendering jitter.
Integer nextOutputBuffer = outputBufferQueue.poll();
if (nextOutputBuffer != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
videoDecoder.releaseOutputBuffer(nextOutputBuffer, frameTimeNanos);
}
else {
videoDecoder.releaseOutputBuffer(nextOutputBuffer, true);
}
activeWindowVideoStats.totalFramesRendered++;
lastRenderedFrameTimeNanos = frameTimeNanos;
activeWindowVideoStats.totalFramesRendered++;
}
}
// Request another callback for next frame
@@ -468,8 +476,9 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
presentationTimeUs = info.presentationTimeUs;
}
if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_MAX_SMOOTHNESS) {
// In max smoothness mode, we want to never drop frames
if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_MAX_SMOOTHNESS ||
prefs.framePacing == PreferenceConfiguration.FRAME_PACING_CAP_FPS) {
// In max smoothness or cap FPS mode, we want to never drop frames
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Use a PTS that will cause this frame to never be dropped
videoDecoder.releaseOutputBuffer(lastIndex, 0);
@@ -5,8 +5,6 @@ import java.io.OutputStream;
import java.io.StringReader;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.LinkedList;
@@ -49,8 +47,7 @@ public class ComputerManagerService extends Service {
private static final int APPLIST_POLLING_PERIOD_MS = 30000;
private static final int APPLIST_FAILED_POLLING_RETRY_MS = 2000;
private static final int MDNS_QUERY_PERIOD_MS = 1000;
private static final int FAST_POLL_TIMEOUT = 1000;
private static final int OFFLINE_POLL_TRIES = 5;
private static final int OFFLINE_POLL_TRIES = 3;
private static final int INITIAL_POLL_TRIES = 2;
private static final int EMPTY_LIST_THRESHOLD = 3;
private static final int POLL_DATA_TTL_MS = 30000;
@@ -528,11 +525,6 @@ public class ComputerManagerService extends Service {
}
private ComputerDetails tryPollIp(ComputerDetails details, String address) {
// Fast poll this address first to determine if we can connect at the TCP layer
if (!fastPollIp(address)) {
return null;
}
try {
NvHTTP http = new NvHTTP(address, idManager.getUniqueId(), details.serverCert,
PlatformBinding.getCryptoProvider(ComputerManagerService.this));
@@ -551,104 +543,113 @@ public class ComputerManagerService extends Service {
return null;
}
// Set the new active address
newDetails.activeAddress = address;
return newDetails;
} catch (XmlPullParserException | IOException e) {
} catch (XmlPullParserException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
return null;
}
}
// Just try to establish a TCP connection to speculatively detect a running
// GFE server
private boolean fastPollIp(String address) {
if (address == null) {
// Don't bother if our address is null
return false;
}
private static class ParallelPollTuple {
public String address;
public ComputerDetails existingDetails;
Socket s = new Socket();
try {
s.connect(new InetSocketAddress(address, NvHTTP.HTTPS_PORT), FAST_POLL_TIMEOUT);
s.close();
return true;
} catch (IOException e) {
return false;
public boolean complete;
public ComputerDetails returnedDetails;
public ParallelPollTuple(String address, ComputerDetails existingDetails) {
this.address = address;
this.existingDetails = existingDetails;
}
}
private void startFastPollThread(final String address, final boolean[] info) {
private void startParallelPollThread(ParallelPollTuple tuple, HashSet<String> uniqueAddresses) {
// Don't bother starting a polling thread for an address that doesn't exist
// or if the address has already been polled with an earlier tuple
if (tuple.address == null || !uniqueAddresses.add(tuple.address)) {
tuple.complete = true;
tuple.returnedDetails = null;
return;
}
Thread t = new Thread() {
@Override
public void run() {
boolean pollRes = fastPollIp(address);
ComputerDetails details = tryPollIp(tuple.existingDetails, tuple.address);
synchronized (info) {
info[0] = true; // Done
info[1] = pollRes; // Polling result
synchronized (tuple) {
tuple.complete = true; // Done
tuple.returnedDetails = details; // Polling result
info.notify();
tuple.notify();
}
}
};
t.setName("Fast Poll - "+address);
t.setName("Parallel Poll - "+tuple.address+" - "+tuple.existingDetails.name);
t.start();
}
private String fastPollPc(final String localAddress, final String remoteAddress, final String manualAddress, final String ipv6Address) throws InterruptedException {
final boolean[] remoteInfo = new boolean[2];
final boolean[] localInfo = new boolean[2];
final boolean[] manualInfo = new boolean[2];
final boolean[] ipv6Info = new boolean[2];
private ComputerDetails parallelPollPc(ComputerDetails details) throws InterruptedException {
ParallelPollTuple localInfo = new ParallelPollTuple(details.localAddress, details);
ParallelPollTuple manualInfo = new ParallelPollTuple(details.manualAddress, details);
ParallelPollTuple remoteInfo = new ParallelPollTuple(details.remoteAddress, details);
ParallelPollTuple ipv6Info = new ParallelPollTuple(details.ipv6Address, details);
startFastPollThread(localAddress, localInfo);
startFastPollThread(remoteAddress, remoteInfo);
startFastPollThread(manualAddress, manualInfo);
startFastPollThread(ipv6Address, ipv6Info);
// These must be started in order of precedence for the deduplication algorithm
// to result in the correct behavior.
HashSet<String> uniqueAddresses = new HashSet<>();
startParallelPollThread(localInfo, uniqueAddresses);
startParallelPollThread(manualInfo, uniqueAddresses);
startParallelPollThread(remoteInfo, uniqueAddresses);
startParallelPollThread(ipv6Info, uniqueAddresses);
// Check local first
synchronized (localInfo) {
while (!localInfo[0]) {
while (!localInfo.complete) {
localInfo.wait(500);
}
if (localInfo[1]) {
return localAddress;
if (localInfo.returnedDetails != null) {
localInfo.returnedDetails.activeAddress = localInfo.address;
return localInfo.returnedDetails;
}
}
// Now manual
synchronized (manualInfo) {
while (!manualInfo[0]) {
while (!manualInfo.complete) {
manualInfo.wait(500);
}
if (manualInfo[1]) {
return manualAddress;
if (manualInfo.returnedDetails != null) {
manualInfo.returnedDetails.activeAddress = manualInfo.address;
return manualInfo.returnedDetails;
}
}
// Now remote IPv4
synchronized (remoteInfo) {
while (!remoteInfo[0]) {
while (!remoteInfo.complete) {
remoteInfo.wait(500);
}
if (remoteInfo[1]) {
return remoteAddress;
if (remoteInfo.returnedDetails != null) {
remoteInfo.returnedDetails.activeAddress = remoteInfo.address;
return remoteInfo.returnedDetails;
}
}
// Now global IPv6
synchronized (ipv6Info) {
while (!ipv6Info[0]) {
while (!ipv6Info.complete) {
ipv6Info.wait(500);
}
if (ipv6Info[1]) {
return ipv6Address;
if (ipv6Info.returnedDetails != null) {
ipv6Info.returnedDetails.activeAddress = ipv6Info.address;
return ipv6Info.returnedDetails;
}
}
@@ -656,41 +657,10 @@ public class ComputerManagerService extends Service {
}
private boolean pollComputer(ComputerDetails details) throws InterruptedException {
ComputerDetails polledDetails;
// Do a TCP-level connection to the HTTP server to see if it's listening.
// Do not write this address to details.activeAddress because:
// a) it's only a candidate and may be wrong (multiple PCs behind a single router)
// b) if it's null, it will be unexpectedly nulling the activeAddress of a possibly online PC
LimeLog.info("Starting fast poll for "+details.name+" ("+details.localAddress +", "+details.remoteAddress +", "+details.manualAddress+", "+details.ipv6Address+")");
String candidateAddress = fastPollPc(details.localAddress, details.remoteAddress, details.manualAddress, details.ipv6Address);
LimeLog.info("Fast poll for "+details.name+" returned candidate address: "+candidateAddress);
// If no connection could be established to either IP address, there's nothing we can do
if (candidateAddress == null) {
return false;
}
// Try using the active address from fast-poll
polledDetails = tryPollIp(details, candidateAddress);
if (polledDetails == null) {
// If that failed, try all unique addresses except what we've
// already tried
HashSet<String> uniqueAddresses = new HashSet<>();
uniqueAddresses.add(details.localAddress);
uniqueAddresses.add(details.manualAddress);
uniqueAddresses.add(details.remoteAddress);
uniqueAddresses.add(details.ipv6Address);
for (String addr : uniqueAddresses) {
if (addr == null || addr.equals(candidateAddress)) {
continue;
}
polledDetails = tryPollIp(details, addr);
if (polledDetails != null) {
break;
}
}
}
// Poll all addresses in parallel to speed up the process
LimeLog.info("Starting parallel poll for "+details.name+" ("+details.localAddress +", "+details.remoteAddress +", "+details.manualAddress+", "+details.ipv6Address+")");
ComputerDetails polledDetails = parallelPollPc(details);
LimeLog.info("Parallel poll for "+details.name+" returned address: "+details.activeAddress);
if (polledDetails != null) {
details.update(polledDetails);
@@ -80,7 +80,8 @@ public class PreferenceConfiguration {
public static final int FRAME_PACING_MIN_LATENCY = 0;
public static final int FRAME_PACING_BALANCED = 1;
public static final int FRAME_PACING_MAX_SMOOTHNESS = 2;
public static final int FRAME_PACING_CAP_FPS = 2;
public static final int FRAME_PACING_MAX_SMOOTHNESS = 3;
public static final String RES_360P = "640x360";
public static final String RES_480P = "854x480";
@@ -288,6 +289,9 @@ public class PreferenceConfiguration {
else if (str.equals("balanced")) {
return FRAME_PACING_BALANCED;
}
else if (str.equals("cap-fps")) {
return FRAME_PACING_CAP_FPS;
}
else if (str.equals("smoothness")) {
return FRAME_PACING_MAX_SMOOTHNESS;
}
@@ -232,6 +232,13 @@ public class StreamSettings extends Activity {
category.removePreference(findPreference("checkbox_enable_pip"));
}
// Fire TV apps are not allowed to use WebViews or browsers, so hide the Help category
/*if (getActivity().getPackageManager().hasSystemFeature("amazon.hardware.fire_tv")) {
PreferenceCategory category =
(PreferenceCategory) findPreference("category_help");
screen.removePreference(category);
}*/
// Remove the vibration options if the device can't vibrate
if (!((Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE)).hasVibrator()) {
PreferenceCategory category =
@@ -0,0 +1,45 @@
package com.limelight.preferences;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.preference.Preference;
import android.util.AttributeSet;
import com.limelight.utils.HelpLauncher;
public class WebLauncherPreference extends Preference {
private String url;
public WebLauncherPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(attrs);
}
public WebLauncherPreference(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public WebLauncherPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initialize(attrs);
}
private void initialize(AttributeSet attrs) {
if (attrs == null) {
throw new IllegalStateException("WebLauncherPreference must have attributes!");
}
url = attrs.getAttributeValue(null, "url");
if (url == null) {
throw new IllegalStateException("WebLauncherPreference must have 'url' attribute!");
}
}
@Override
public void onClick() {
HelpLauncher.launchUrl(getContext(), url);
}
}
@@ -8,7 +8,7 @@ import android.net.Uri;
import com.limelight.HelpActivity;
public class HelpLauncher {
private static void launchUrl(Context context, String url) {
public static void launchUrl(Context context, String url) {
// Try to launch the default browser
try {
Intent i = new Intent(Intent.ACTION_VIEW);
+2
View File
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
+24 -5
View File
@@ -97,7 +97,6 @@
<string name="perf_overlay_renderingfps">Wiedergabe-Bildwiederholungsrate: %1$.2f FPS</string>
<string name="perf_overlay_netdrops">Wegen Netzwerkübertragung ausgelassene Frames: %1$.2f%%</string>
<string name="perf_overlay_dectime">Durchschnittliche Dekodierungszeit: %1$.2f ms</string>
<!-- AppList activity -->
<string name="applist_connect_msg">Verbinde mit Host…</string>
<string name="applist_menu_resume">Sitzung wiederherstellen</string>
@@ -133,7 +132,7 @@
<string name="summary_fps_list">Erhöhen für einen gleichmäßigeren Video-Stream. Verringern um auf langsameren Geräten eine bessere Performance zu erzielen.</string>
<string name="title_seekbar_bitrate">Video Bitrate</string>
<string name="summary_seekbar_bitrate">Erhöhen für einen schärferen Video-Stream. Verringern um auf langsameren Geräten eine bessere Performance zu erzielen.</string>
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
<string name="suffix_seekbar_bitrate_mbps">Mbit/s</string>
<string name="title_checkbox_stretch_video">Video auf Vollbildschirm strecken</string>
<string name="category_audio_settings">Audio Einstellungen</string>
<string name="title_audio_config_list">Surround Sound Konfiguration </string>
@@ -192,8 +191,8 @@
<string name="title_checkbox_disable_warnings">Warnhinweise deaktivieren</string>
<string name="summary_checkbox_disable_warnings">On-Screen Warnmeldungen während des Streaming deaktivieren</string>
<string name="summary_disable_frame_drop">Kann das Mikro-Ruckeln auf einigen Geräten reduzieren, allerdings erhöht dies gleichzeitig die Latenz</string>
<string name="title_video_format">H265 Einstellungen ändern</string>
<string name="summary_video_format">H265 verringert die Video-Bandbreitenanforderung, funktioniert allerdings nur auf sehr neuen Geräten</string>
<string name="title_video_format">HEVC Einstellungen ändern</string>
<string name="summary_video_format">HEVC verringert die Video-Bandbreitenanforderung, funktioniert allerdings nur auf sehr neuen Geräten</string>
<string name="title_enable_hdr">HDR aktivieren (experimentell)</string>
<string name="summary_enable_hdr">HDR-Streaming sofern dies von der Host-GPU unterstützt wird. HDR erfordert eine GPU der GTX 1000 Serie oder neuer.</string>
<string name="title_enable_perf_overlay">Performance Overlay aktivieren</string>
@@ -218,9 +217,29 @@
<string name="pcview_menu_header_unknown">Aktualisiere</string>
<string name="pcview_menu_header_offline">Offline</string>
<string name="pcview_menu_header_online">Online</string>
<!-- Array strings -->
<string name="videoformat_hevcauto">Verwende HEVC so fern stabile Unterstützung vorhanden ist</string>
<string name="videoformat_hevcalways">Immer HEVC verwenden (könnte Crashes verursachen)</string>
<string name="videoformat_hevcnever">Nie HEVC verwenden</string>
<string name="title_frame_pacing">Video Frame-Pacing</string>
<string name="summary_frame_pacing">Lege fest, wie die Videolatenz und die flüssige Wiedergabe ausgeglichen werden sollen</string>
<string name="resolution_prefix_native_fullscreen">Natives Vollbild</string>
<string name="pacing_latency">Bevorzuge niedrigste Latenz</string>
<string name="pacing_balanced">Ausgeglichen</string>
<string name="pacing_smoothness">Bevorzuge flüssige Bildwiedergabe (kann die Latenzzeit deutlich erhöhen)</string>
<string name="perf_overlay_streamdetails">Video Stream: %1$s %2$.2f FPS</string>
<string name="resolution_360p">360p</string>
<string name="resolution_1080p">1080p</string>
<string name="resolution_1440p">1440p</string>
<string name="resolution_4k">4K</string>
<string name="audioconf_stereo">Stereo</string>
<string name="audioconf_51surround">5.1 Surround Sound</string>
<string name="audioconf_71surround">7.1 Surround Sound</string>
<string name="perf_overlay_netlatency">Durchschnittliche Netzwerklatenz: %1$d ms (Abweichung: %2$d ms)</string>
<string name="fps_30">30 FPS</string>
<string name="resolution_480p">480p</string>
<string name="fps_120">120 FPS</string>
<string name="resolution_720p">720p</string>
<string name="fps_60">60 FPS</string>
<string name="fps_90">90 FPS</string>
</resources>
+11 -4
View File
@@ -220,19 +220,26 @@
<string name="resolution_prefix_native_fullscreen">Plein-écran natif</string>
<string name="perf_overlay_netlatency">Latence réseau moyenne : %1$d ms (variance : %2$d ms)</string>
<string name="perf_overlay_streamdetails">Stream vidéo : %1$s %2$.2f FPS</string>
<!-- Array strings -->
<string name="fps_30">30 IPS</string>
<string name="fps_60">60 IPS</string>
<string name="fps_90">90 IPS</string>
<string name="fps_120">120 IPS</string>
<string name="audioconf_stereo">Stéréo</string>
<string name="audioconf_51surround">Son surround 5.1</string>
<string name="audioconf_71surround">Son surround 7.1</string>
<string name="videoformat_hevcauto">Utiliser HEVC uniquement s\'il est stable</string>
<string name="videoformat_hevcalways">Utilisez toujours HEVC (mais il peut planter)</string>
<string name="videoformat_hevcnever">N\'utilisez jamais HEVC</string>
<string name="title_frame_pacing">Frame-pacing vidéo</string>
<string name="summary_frame_pacing">Spécifiez comment équilibrer latence et fluidité de la vidéo</string>
<string name="pacing_latency">Préférer une latence plus faible</string>
<string name="pacing_balanced">Équilibré</string>
<string name="resolution_720p">720p</string>
<string name="pacing_smoothness">Préférer la qualité vidéo (risque d\'augmenter la latence)</string>
<string name="resolution_360p">360p</string>
<string name="resolution_480p">480p</string>
<string name="resolution_1440p">1440p</string>
<string name="resolution_1080p">1080p</string>
<string name="resolution_4k">4K</string>
</resources>
+230 -1
View File
@@ -1,2 +1,231 @@
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
<resources>
<string name="title_frame_pacing">Ritmo de quadros</string>
<string name="pacing_balanced">Balanceado</string>
<string name="pacing_latency">Preferir baixa latência</string>
<string name="summary_enable_hdr">Transmita HDR quando o jogo e a GPU do PC suportarem. O HDR requer uma GPU da série GTX 1000 ou posterior.</string>
<string name="summary_enable_post_stream_toast">Exibe uma mensagem com informações de latência após o término da transmissão</string>
<string name="summary_unlock_fps">Transmitir a 90 ou 120 FPS pode reduzir a latência em dispositivos de última geração, mas pode causar atraso ou instabilidade em dispositivos que não suportam</string>
<string name="summary_checkbox_vibrate_osc">Vibra seu dispositivo para emular rumble nos controles de tela</string>
<string name="pcview_menu_header_offline">Indisponível</string>
<string name="pcview_menu_header_unknown">Atualizando</string>
<string name="pacing_smoothness">Preferir vídeo mais suave (pode aumentar significativamente a latência)</string>
<string name="summary_frame_pacing">Especifique o equilíbrio entre latência e suavidade do vídeo</string>
<string name="title_checkbox_disable_warnings">Desabilitar mensagens de alerta</string>
<string name="title_checkbox_enable_pip">Habilitar modo Picture-in-Picture</string>
<string name="summary_checkbox_small_icon_mode">Diminui o tamanho dos ícones permitindo que mais aplicativos sejam visíveis na tela</string>
<string name="dialog_text_reset_osc">Tem certeza de que deseja excluir o layout salvo dos controles de tela\?</string>
<string name="summary_checkbox_touchscreen_trackpad">Se habilitado, a tela sensível ao toque funciona como um trackpad. Se desativado, a tela controla diretamente o cursor do mouse.</string>
<string name="summary_checkbox_xb1_driver">Habilita um driver USB integrado para dispositivos sem suporte nativo aos controles Xbox</string>
<string name="title_checkbox_mouse_nav_buttons">Habilitar os botões de voltar e avançar do mouse</string>
<string name="addpc_fail">Não foi possível conectar ao computador especificado. Certifique-se de que as portas necessárias sejam permitidas pelo firewall.</string>
<string name="conn_error_msg">Falha ao iniciar</string>
<string name="ip_hint">Endereço de IP do PC GeForce</string>
<string name="searching_pc">Procurando por PCs rodando o GameStream...
\n
\nCertifique-se de que o GameStream esteja ativado nas configurações do SHIELD do GeForce Experience.</string>
<string name="nettest_text_success">Sua rede não parece estar bloqueando o Moonlight. Se você ainda tiver problemas para se conectar, verifique as configurações de firewall do seu PC.
\n
\nSe você estiver tentando transmitir pela Internet, instale o Moonlight Internet Hosting Tool em seu PC e execute o Internet Streaming Tester para verificar a conexão com a Internet do seu PC.</string>
<string name="check_ports_msg">Verifique o firewall e permita a(s) seguinte(s) para porta(s):</string>
<string name="wol_no_mac">Não foi possível acordar o PC porque o GFE não enviou um endereço MAC</string>
<string name="wol_waking_msg">Pode levar alguns segundos para o seu PC acordar. Se isso não acontecer, verifique se ele está configurado corretamente para Wake-On-LAN.</string>
<string name="error_404">GFE retornou um erro HTTP 404. Verifique se o seu PC está executando uma GPU compatível. O uso do software de área de trabalho remota também pode causar esse erro. Tente reiniciar sua máquina ou reinstalar o GFE.</string>
<string name="message_decoding_error">Moonlight crashou devido a uma incompatibilidade com o decodificador de vídeo deste dispositivo. Certifique-se de que o GeForce Experience esteja atualizado para a versão mais recente em seu PC. Tente ajustar as configurações de transmissão se as falhas continuarem.</string>
<string name="message_decoding_reset">O decodificador de vídeo do seu dispositivo continua crashando nas configurações de transmissão selecionadas. Suas configurações de transmissão foram redefinidas para o padrão.</string>
<string name="error_usb_prohibited">O acesso USB é proibido pelo administrador do seu dispositivo. Verifique suas configurações de Knox ou MDM.</string>
<string name="unable_to_pin_shortcut">Seu launcher atual não permite a criação de atalhos fixados.</string>
<string name="video_decoder_init_failed">Falha ao iniciar o decodificador de vídeo. Seu dispositivo pode não suportar a resolução ou taxa de quadros selecionada.</string>
<string name="no_video_received_error">Nenhum vídeo recebido do host.</string>
<string name="no_frame_received_error">Sua conexão de rede não está funcionando bem. Reduza a configuração da taxa de bits do vídeo ou tente uma conexão mais rápida.</string>
<string name="early_termination_error">Algo deu errado no seu PC ao iniciar a transmissão.
\n
\nCertifique-se de não ter nenhum conteúdo protegido por DRM aberto em seu PC. Você também pode tentar reiniciar ele.
\n
\nSe o problema persistir, tente reinstalar os drivers da GPU e o GeForce Experience.</string>
<string name="conn_establishing_msg">Iniciando a conexão</string>
<string name="conn_establishing_title">Estabelecendo Conexão</string>
<string name="resolution_360p">360p</string>
<string name="resolution_480p">480p</string>
<string name="resolution_720p">720p</string>
<string name="resolution_1080p">1080p</string>
<string name="resolution_1440p">1440p</string>
<string name="resolution_4k">4K</string>
<string name="fps_30">30 FPS</string>
<string name="fps_60">60 FPS</string>
<string name="videoformat_hevcalways">Sempre usar HEVC (talvez crashe)</string>
<string name="videoformat_hevcauto">Usar HEVC apenas se for estável</string>
<string name="fps_120">120 FPS</string>
<string name="audioconf_stereo">Stereo</string>
<string name="audioconf_51surround">5.1 Surround</string>
<string name="audioconf_71surround">7.1 Surround</string>
<string name="fps_90">90 FPS</string>
<string name="videoformat_hevcnever">Nunca usar HEVC</string>
<string name="scut_deleted_pc">PC deletado</string>
<string name="scut_not_paired">PC não pareado</string>
<string name="help_loading_title">Ver Ajuda</string>
<string name="help_loading_msg">Carregando página de ajuda…</string>
<string name="scut_pc_not_found">PC não encontrado</string>
<string name="scut_invalid_uuid">O PC informado não é válido</string>
<string name="scut_invalid_app_id">O aplicativo informado não é válido</string>
<string name="pcview_menu_header_online">Disponível</string>
<string name="pcview_menu_app_list">Ver Todos os Jogos</string>
<string name="pcview_menu_unpair_pc">Desparear</string>
<string name="pcview_menu_delete_pc">Deletar PC</string>
<string name="pcview_menu_test_network">Testar Conexão com a Internet</string>
<string name="pcview_menu_details">Ver Detalhes</string>
<string name="nettest_title_waiting">Testando a Conexão com a Internet</string>
<string name="nettest_title_done">Teste de Internet Completo</string>
<string name="pcview_menu_pair_pc">Parear com o PC</string>
<string name="pcview_menu_send_wol">Enviar Wake-On-LAN</string>
<string name="nettest_text_waiting">O Moonlight está testando a sua internet para determinar se o NVIDIA GameStream está bloqueado.
\n
\nIsso pode levar alguns segundos…</string>
<string name="nettest_text_inconclusive">O teste de rede não pôde ser executado porque nenhum dos servidores de teste de conexão do Moonlight estava acessível. Verifique sua conexão com a Internet ou tente novamente mais tarde.</string>
<string name="nettest_text_failure">A conexão de rede atual do seu dispositivo parece estar bloqueando o Moonlight. A transmissão pela Internet pode não funcionar enquanto estiver conectado a esta rede.
\n
\nAs seguintes portas de rede estão bloqueadas:
\n</string>
<string name="nettest_text_blocked">A conexão de rede atual do seu dispositivo está bloqueando o Moonlight. A transmissão pela Internet pode não funcionar enquanto estiver conectado a esta rede.</string>
<string name="pairing">Pareando…</string>
<string name="pair_pc_offline">Esse computador está indisponível</string>
<string name="pair_pc_ingame">Esse computador está atualmente em um jogo. Você deve fechar o jogo antes de parear.</string>
<string name="pair_pairing_title">Pareando</string>
<string name="pair_pairing_msg">Insira o seguinte PIN no PC de destino:</string>
<string name="pair_incorrect_pin">PIN incorreto</string>
<string name="pair_fail">Falha no pareamento</string>
<string name="pair_already_in_progress">Pareamento já em andamento</string>
<string name="wol_pc_online">Esse computador está disponível</string>
<string name="wol_waking_pc">Acordando o PC…</string>
<string name="wol_fail">Falha ao enviar pacotes Wake-On-LAN</string>
<string name="unpairing">Despareando…</string>
<string name="unpair_success">Despareado com sucesso</string>
<string name="unpair_fail">Falha ao desparear</string>
<string name="unpair_error">Dispositivo não pareado</string>
<string name="error_pc_offline">Esse computador está indisponível</string>
<string name="error_manager_not_running">O serviço ComputerManager não está em execução. Aguarde alguns segundos ou reinicie o aplicativo.</string>
<string name="error_unknown_host">Falha ao encontrar o host</string>
<string name="conn_terminated_msg">A conexão foi encerrada</string>
<string name="yes">Sim</string>
<string name="no">Não</string>
<string name="lost_connection">Conexão perdida com o PC</string>
<string name="title_details">Detalhes</string>
<string name="help">Ajuda</string>
<string name="delete_pc_msg">Tem certeza de que deseja excluir este PC\?</string>
<string name="slow_connection_msg">Conexão lenta com o PC
\nReduza sua taxa de bits</string>
<string name="poor_connection_msg">Conexão ruim com o PC</string>
<string name="conn_terminated_title">Conexão Encerrada</string>
<string name="title_decoding_error">Decodificador de Vídeo Crashou</string>
<string name="title_decoding_reset">Resetar Configurações de Vídeo</string>
<string name="conn_metered">Aviso: Sua conexão de rede atual é limitada!</string>
<string name="conn_client_latency">Latência média de decodificação de quadros:</string>
<string name="conn_client_latency_hw">latência do decodificador de hardware:</string>
<string name="conn_hardware_latency">Latência média de decodificação de hardware:</string>
<string name="conn_starting">Iniciando</string>
<string name="conn_error_title">Erro de Conexão</string>
<string name="perf_overlay_decoder">Decodificador: %1$s</string>
<string name="perf_overlay_incomingfps">Taxa de quadros recebidos pela rede:: %1$.2f FPS</string>
<string name="perf_overlay_renderingfps">Taxa de quadros renderizando: %1$.2f FPS</string>
<string name="perf_overlay_streamdetails">Transmissão: %1$s %2$.2f FPS</string>
<string name="perf_overlay_netlatency">Latência média da rede: %1$d ms (variação: %2$d ms)</string>
<string name="perf_overlay_dectime">Tempo médio de decodificação: %1$.2f ms</string>
<string name="applist_connect_msg">Conectando ao PC…</string>
<string name="applist_menu_resume">Retornar ao Jogo</string>
<string name="applist_menu_quit">Sair do Jogo</string>
<string name="applist_menu_quit_and_start">Sair do Jogo Atual e Iniciar</string>
<string name="applist_menu_cancel">Cancelar</string>
<string name="applist_menu_details">Ver Detalhes</string>
<string name="applist_menu_scut">Criar Atalho</string>
<string name="applist_menu_tv_channel">Adicionar ao Canal</string>
<string name="applist_menu_hide_app">Esconder Jogo</string>
<string name="applist_refresh_title">Lista de Aplicativos</string>
<string name="perf_overlay_netdrops">Quadros dropados pela rede: %1$.2f%%</string>
<string name="applist_quit_app">Saindo</string>
<string name="applist_quit_success">Saiu com sucesso</string>
<string name="applist_quit_fail">Falha ao sair</string>
<string name="applist_refresh_msg">Recarregando aplicativos…</string>
<string name="applist_refresh_error_title">Erro</string>
<string name="applist_refresh_error_msg">Falha ao obter a lista de aplicativos</string>
<string name="applist_quit_confirmation">Tem certeza de que deseja sair do aplicativo em execução\? Todos os dados não salvos serão perdidos.</string>
<string name="applist_details_id">ID do App:</string>
<string name="title_add_pc">Adicionar PC Manualmente</string>
<string name="msg_add_pc">Conectando ao PC…</string>
<string name="addpc_success">Computador adicionado com sucesso</string>
<string name="addpc_unknown_host">Não foi possível encontrar o PC. Certifique-se de que não cometeu um erro de digitação no endereço.</string>
<string name="addpc_enter_ip">Você deve inserir um endereço de IP</string>
<string name="category_input_settings">Configurações de Controles</string>
<string name="category_basic_settings">Configurações Básicas</string>
<string name="title_resolution_list">Resolução</string>
<string name="summary_resolution_list">Aumente para melhorar a clareza da imagem. Diminua para melhor desempenho em dispositivos de baixo custo e redes mais lentas.</string>
<string name="title_native_res_dialog">Alerta de Resolução Nativa</string>
<string name="text_native_res_dialog">Os modos de resolução nativa não são oficialmente suportados pelo GeForce Experience, portanto, ele não definirá a resolução da tela do host. Você precisará configurá-lo manualmente durante o jogo.
\n
\nSe você optar por criar uma resolução personalizada no Painel de controle da NVIDIA para corresponder à resolução do seu dispositivo, certifique-se de ter lido e entendido o aviso da NVIDIA sobre possíveis danos ao monitor, instabilidade do PC e outros problemas potenciais.
\n
\nNão nos responsabilizamos por quaisquer problemas resultantes da criação de uma resolução personalizada em seu PC.
\n
\nPor fim, seu dispositivo ou PC host pode não suportar transmissões na resolução nativa. Se não funcionar no seu dispositivo, você está sem sorte, infelizmente.</string>
<string name="title_fps_list">Taxa de quadros por segundo</string>
<string name="summary_fps_list">Aumente para uma transmissão de vídeo mais suave. Diminua para melhor desempenho em dispositivos de baixo custo.</string>
<string name="title_seekbar_bitrate">Taxa de bits</string>
<string name="summary_seekbar_bitrate">Aumente para uma melhor qualidade de imagem. Diminua para melhorar o desempenho em conexões mais lentas.</string>
<string name="title_checkbox_stretch_video">Esticar vídeo para tela cheia</string>
<string name="resolution_prefix_native">Nativa</string>
<string name="resolution_prefix_native_fullscreen">Nativa Tela Cheia</string>
<string name="category_audio_settings">Configurações de Áudio</string>
<string name="title_audio_config_list">Configurações de som Surround</string>
<string name="summary_audio_config_list">Habilita o som Surround 5.1 ou 7.1 para sistemas de home theater</string>
<string name="addpc_wrong_sitelocal">Esse endereço não parece certo. Você deve usar o endereço de IP público do seu roteador para transmitir pela Internet.</string>
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
<string name="title_checkbox_show_onscreen_controls">Mostrar controles na tela</string>
<string name="summary_checkbox_show_onscreen_controls">Habilita o controle virtual na tela de toque</string>
<string name="title_checkbox_vibrate_osc">Habilitar vibração</string>
<string name="title_only_l3r3">Mostrar somente L3 e R3</string>
<string name="summary_only_l3r3">Esconde todos os botões virtuais exceto o L3 e R3</string>
<string name="title_checkbox_touchscreen_trackpad">Usar a tela como um trackpad</string>
<string name="title_checkbox_multi_controller">Detecção automática de gamepad</string>
<string name="summary_checkbox_multi_controller">Desmarque esta opção para forçar o gamepad a estar sempre presente</string>
<string name="title_checkbox_vibrate_fallback">Emular suporte rumble com vibração</string>
<string name="summary_checkbox_vibrate_fallback">Vibra seu dispositivo para emular rumble se seu gamepad não suportar</string>
<string name="title_seekbar_deadzone">Ajustar zona morta do analógico</string>
<string name="suffix_seekbar_deadzone">%</string>
<string name="title_checkbox_xb1_driver">Driver de gamepad USB Xbox 360/One</string>
<string name="title_checkbox_usb_bind_all">Substituir o suporte nativo ao gamepad do Xbox</string>
<string name="summary_checkbox_usb_bind_all">Use o driver USB do Moonlight para todos os gamepads suportados, mesmo se houver suporte nativo ao controle Xbox</string>
<string name="title_checkbox_mouse_emulation">Emulação de mouse via gamepad</string>
<string name="summary_checkbox_mouse_emulation">Segure o botão Start para mudar o gamepad para o modo de mouse</string>
<string name="summary_checkbox_mouse_nav_buttons">Ativar esta opção pode bugar o clique com o botão direito em alguns dispositivos com bugs</string>
<string name="summary_checkbox_flip_face_buttons">Inverte os botões A/B e X/Y dos gamepads e controles de tela</string>
<string name="category_on_screen_controls_settings">Configurações de Controles de Tela</string>
<string name="title_checkbox_flip_face_buttons">Inverter botões</string>
<string name="title_unlock_fps">Liberar todas as taxas de quadros possíveis</string>
<string name="category_advanced_settings">Configurações Avançadas</string>
<string name="title_checkbox_host_audio">Reproduzir áudio no PC</string>
<string name="summary_checkbox_host_audio">Reproduz o áudio do computador e deste dispositivo</string>
<string name="title_checkbox_enable_sops">Otimizar configurações de jogo</string>
<string name="summary_checkbox_enable_sops">Permitir que o GFE modifique as configurações do jogo para otimizar a transmissão</string>
<string name="title_language_list">Idioma</string>
<string name="summary_language_list">Idioma para ser usado no Moonlight</string>
<string name="summary_checkbox_enable_pip">Permite que a transmissão seja visualizada (mas não controlada) enquanto usa outros apps</string>
<string name="category_ui_settings">Configurações de Interface</string>
<string name="suffix_osc_opacity">%</string>
<string name="category_host_settings">Configurações de Host</string>
<string name="dialog_title_osc_opacity">Mudar opacidade</string>
<string name="title_checkbox_small_icon_mode">Mostrar ícones menores</string>
<string name="summary_reset_osc">Redefine todos os controles na tela para seu tamanho e posição padrão</string>
<string name="dialog_title_reset_osc">Resetar Layout</string>
<string name="toast_reset_osc_success">Controles de tela redefinidos para o padrão</string>
<string name="title_osc_opacity">Mudar a opacidade dos controles de tela</string>
<string name="summary_osc_opacity">Deixe os controles de tela mais/menos transparentes</string>
<string name="title_reset_osc">Limpar o layout salvo dos controles de tela</string>
<string name="title_video_format">Mudar configurações do HEVC</string>
<string name="summary_video_format">HEVC reduz os requisitos de largura de banda de vídeo, mas requer um dispositivo mais atual</string>
<string name="summary_checkbox_disable_warnings">Desativa as mensagens de aviso de conexão na tela durante a transmissão</string>
<string name="title_disable_frame_drop">Nunca dropar quadros</string>
<string name="summary_disable_frame_drop">Talvez reduza o micro-stuttering em alguns dispositivos, mas pode aumentar a latência</string>
<string name="title_enable_hdr">Habilitar HDR (Experimental)</string>
<string name="title_enable_post_stream_toast">Mostrar aviso de latência após terminar a transmissão</string>
<string name="summary_enable_perf_overlay">Exibe informações de performance em tempo real durante a transmissão</string>
<string name="title_enable_perf_overlay">Mostrar status de performance durante a transmissão</string>
</resources>
+4
View File
@@ -13,4 +13,8 @@
<string name="pcview_menu_header_offline">Offline</string>
<string name="pcview_menu_app_list">Veja todos aplicativos</string>
<string name="pcview_menu_pair_pc">Sincronize com o PC</string>
<string name="pcview_menu_details">Ver Detalhes</string>
<string name="pair_pairing_title">Pareando</string>
<string name="pair_fail">Falha no pareamento</string>
<string name="nettest_title_waiting">Testar Conexão com a Internet</string>
</resources>
+18 -1
View File
@@ -217,9 +217,26 @@
<string name="pcview_menu_header_unknown">Оновлення</string>
<string name="pcview_menu_header_offline">Поза мережею</string>
<string name="pcview_menu_header_online">В мережі</string>
<!-- Array strings -->
<string name="videoformat_hevcauto">Використовувати HEVC тільки якщо безпечно</string>
<string name="videoformat_hevcalways">Завжди використовувати HEVC якщо доступно</string>
<string name="videoformat_hevcnever">Ніколи не використовувати HEVC</string>
<string name="title_frame_pacing">Швидкість кадрів відео</string>
<string name="summary_frame_pacing">Укажіть баланс відео затримки та плавності</string>
<string name="pacing_latency">Перевага найменшій затримці</string>
<string name="pacing_smoothness">Перевага плавному відео (може значно збільшити затримку)</string>
<string name="pacing_balanced">Збалансовано</string>
<string name="resolution_360p">360p</string>
<string name="resolution_480p">480p</string>
<string name="resolution_720p">720p</string>
<string name="resolution_1080p">1080p</string>
<string name="resolution_1440p">1440p</string>
<string name="resolution_4k">4K</string>
<string name="fps_30">30 кадрів/сек</string>
<string name="fps_60">60 кадрів/сек</string>
<string name="fps_90">90 кадрів/сек</string>
<string name="fps_120">120 кадрів/сек</string>
<string name="audioconf_stereo">Стерео</string>
<string name="audioconf_51surround">5.1 Об\'ємний Звук</string>
<string name="audioconf_71surround">7.1 Об\'ємний Звук</string>
</resources>
+11 -2
View File
@@ -218,13 +218,22 @@
<string name="perf_overlay_netlatency">平均网络延迟: %1$d ms (抖动: %2$d ms)</string>
<string name="perf_overlay_streamdetails">视频流: %1$s %2$.2f FPS</string>
<string name="resolution_prefix_native_fullscreen">本地全屏</string>
<!-- Array strings -->
<string name="audioconf_stereo">立体声</string>
<string name="audioconf_51surround">5.1环绕声</string>
<string name="audioconf_71surround">7.1环绕声</string>
<string name="videoformat_hevcauto">如果稳定才使用HEVC</string>
<string name="videoformat_hevcalways">强制使用HEVC(不稳定)</string>
<string name="videoformat_hevcnever">不使用HEVC</string>
<string name="title_frame_pacing">视频帧速调节</string>
<string name="resolution_360p">360p</string>
<string name="resolution_480p">480p</string>
<string name="resolution_1440p">1440p</string>
<string name="resolution_4k">4K</string>
<string name="fps_30">30 FPS</string>
<string name="fps_60">60 FPS</string>
<string name="fps_90">90 FPS</string>
<string name="fps_120">120 FPS</string>
<string name="resolution_1080p">1080p</string>
<string name="resolution_720p">720p</string>
</resources>
+24 -18
View File
@@ -40,7 +40,7 @@
<string name="error_pc_offline"> 電腦離線中 </string>
<string name="error_manager_not_running">ComputerManager 服務未執行。請稍等幾秒或重啟應用程式。</string>
<string name="error_unknown_host"> 無法解析主機位址 </string>
<string name="error_404">GFE 返回了 HTTP 404 錯誤。確保你的電腦顯卡支援串流。使用遠端桌面軟體同樣會引起此錯誤,請嘗試重啟電腦或重新安裝 GFE。</string>
<string name="error_404">GFE 返回了 HTTP 404 錯誤。確保你的電腦顯卡支援串流。使用遠端桌面軟體同樣會引起此錯誤,請嘗試重啟電腦或重新安裝 GFE。</string>
<string name="title_decoding_error">視訊解碼器崩潰</string>
<string name="message_decoding_error">由於與該裝置的視訊解碼器不相容,Moonlight 已崩潰。確保你電腦上的 GFE 已更新至最新版本,如果崩潰繼續,請嘗試調整串流設定。</string>
<string name="title_decoding_reset">重設視訊設定</string>
@@ -80,9 +80,9 @@
<string name="perf_overlay_dectime">平均解碼時間:%1$.2f ms</string>
<!-- AppList activity -->
<string name="applist_connect_msg">正在連線電腦……</string>
<string name="applist_menu_resume">恢復對話</string>
<string name="applist_menu_quit">退出對話</string>
<string name="applist_menu_quit_and_start">退出目前遊戲並開始這個遊戲</string>
<string name="applist_menu_resume">恢復工作階段</string>
<string name="applist_menu_quit">結束工作階段</string>
<string name="applist_menu_quit_and_start">結束目前遊戲並開始這個遊戲</string>
<string name="applist_menu_cancel"> 取消 </string>
<string name="applist_menu_details">檢視詳細資料</string>
<string name="applist_menu_scut">創建捷徑</string>
@@ -91,10 +91,10 @@
<string name="applist_refresh_msg">重新整理中……</string>
<string name="applist_refresh_error_title"> 錯誤 </string>
<string name="applist_refresh_error_msg">獲取遊戲清單失敗</string>
<string name="applist_quit_app"> 退出中 </string>
<string name="applist_quit_success">退出成功</string>
<string name="applist_quit_fail">退出失敗</string>
<string name="applist_quit_confirmation">您確定要退出執行中的遊戲?所有未儲存的資料將丟失。</string>
<string name="applist_quit_app">結束中</string>
<string name="applist_quit_success">結束成功</string>
<string name="applist_quit_fail">結束失敗</string>
<string name="applist_quit_confirmation">您確定要結束執行中的遊戲?所有未儲存的資料將丟失。</string>
<string name="applist_details_id">App ID</string>
<!-- Add computer manually activity -->
<string name="title_add_pc">手動新增電腦</string>
@@ -126,14 +126,14 @@
<string name="title_checkbox_touchscreen_trackpad">將觸控式螢幕作為觸控板使用</string>
<string name="summary_checkbox_touchscreen_trackpad">如果啟用,則將觸控式螢幕作為觸控板使用。 如果停用,則觸控式螢幕直接控制滑鼠游標。</string>
<string name="title_checkbox_multi_controller">自動偵測手把</string>
<string name="summary_checkbox_multi_controller">禁用此項所有手把將視為一個手把</string>
<string name="summary_checkbox_multi_controller">取消此項所有手把將視為一個手把</string>
<string name="title_checkbox_vibrate_fallback">用震動仿真遊戲低頻音</string>
<string name="summary_checkbox_vibrate_fallback">如果你的手把不支援震動,則震動裝置以仿真遊戲低頻音</string>
<string name="title_seekbar_deadzone">調整類比搖杆死區</string>
<string name="suffix_seekbar_deadzone">%</string>
<string name="title_checkbox_xb1_driver">Xbox 360/One USB 手把驅動程式</string>
<string name="summary_checkbox_xb1_driver">為缺少原生 Xbox 控制器支援的裝置啟用內建 USB 驅動程式</string>
<string name="title_checkbox_usb_bind_all">原生 Xbox 手把支援</string>
<string name="title_checkbox_usb_bind_all">原生 Xbox 手把支援</string>
<string name="summary_checkbox_usb_bind_all">強制 Moonlight 的 USB 驅動程式接管所有受支援的原生 Xbox 控制器</string>
<string name="title_checkbox_mouse_emulation">透過手把仿真滑鼠</string>
<string name="summary_checkbox_mouse_emulation">長按開始鍵將手把切換為滑鼠模式</string>
@@ -166,25 +166,25 @@
<string name="category_advanced_settings">進階設定</string>
<string name="title_disable_frame_drop">永不丟失影格</string>
<string name="summary_disable_frame_drop">可能會減少在一些裝置上的卡頓,但會增加延時</string>
<string name="title_video_format"> HEVC 設定</string>
<string name="title_video_format">更 HEVC 設定</string>
<string name="summary_video_format">HEVC 能降低視訊頻寬需求,但需要較新的裝置才能支援</string>
<string name="title_enable_hdr">啟用 HDR (實驗)</string>
<string name="summary_enable_hdr">當遊戲和顯卡支援時以 HDR 模式串流。 HDR 需要 GTX 1000 系列或更高規格顯卡。</string>
<string name="title_enable_hdr">啟用 HDR (實驗)</string>
<string name="summary_enable_hdr">當遊戲和顯卡支援時以 HDR 模式串流。 HDR 需要 GTX 1000 系列或更高規格顯卡。</string>
<string name="title_enable_perf_overlay">顯示效能資訊</string>
<string name="summary_enable_perf_overlay">在串流中顯示即時效能資訊</string>
<string name="title_enable_post_stream_toast">串流完畢顯示延時資訊</string>
<string name="summary_enable_post_stream_toast">串流結束後顯示延時資訊</string>
<string name="title_osc_opacity">螢幕按鈕透明度</string>
<string name="dialog_title_osc_opacity">透明度</string>
<string name="title_osc_opacity">更螢幕按鈕透明度</string>
<string name="dialog_title_osc_opacity">變更不透明度</string>
<string name="suffix_osc_opacity">%</string>
<string name="summary_osc_opacity">令螢幕按钮變得更透明/更不透明</string>
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
<string name="resolution_prefix_native">本機</string>
<string name="text_native_res_dialog">本機解析度模式不受 GFE 的官方支援,因此不會自動設定主機的顯示解析度。您需要在遊戲中手動進行設定。
\n
\n如果您選擇在 NVIDIA 控制台中創建自訂解析度以匹配裝置解析度,請確保您已閱讀並理解 NVIDIA 關於可能導致顯示器損毀和電腦不穩定以及其他潛在問題的警告。
\n如果您選擇在 NVIDIA 控制面板中建立自訂解析度以匹配裝置解析度,請確保您已閱讀並理解 NVIDIA 關於可能導致監視器損毀和電腦不穩定以及其他潛在問題的警告。
\n
\n對於您在您的電腦上建自訂解析度而導致的任何問題,我們概不負責。
\n對於您在您的電腦上建自訂解析度而導致的任何問題,我們概不負責。
\n
\n最後,您的裝置或主機電腦可能不支援以本機解析度串流。如果此模式在您的裝置上無法正常執行,只能說您運氣欠佳了。</string>
<string name="title_native_res_dialog">本機解析度警告</string>
@@ -220,7 +220,7 @@
<string name="perf_overlay_streamdetails">視訊串流:%1$s %2$.2f FPS</string>
<string name="resolution_prefix_native_fullscreen">本機全螢幕</string>
<!-- Array strings -->
<string name="audioconf_stereo">身歷</string>
<string name="audioconf_stereo">立體</string>
<string name="audioconf_51surround">5.1 環場音效</string>
<string name="audioconf_71surround">7.1 環場音效</string>
<string name="videoformat_hevcauto">僅在穩定時使用 HEVC</string>
@@ -236,4 +236,10 @@
<string name="resolution_480p">480P</string>
<string name="resolution_1080p">1080P</string>
<string name="resolution_1440p">1440P</string>
<string name="title_frame_pacing">視訊影格調步</string>
<string name="summary_frame_pacing">指定如何平衡視訊延遲和平滑度</string>
<string name="pacing_balanced">平衡</string>
<string name="pacing_smoothness">偏好平滑視訊 (可能顯著提高延遲)</string>
<string name="pacing_latency">偏好低延遲</string>
<string name="pacing_balanced_alt">FPS 上限平衡 (在某些裝置上可能有更好的表現)</string>
</resources>
+2
View File
@@ -98,11 +98,13 @@
<string-array name="video_frame_pacing_names">
<item>@string/pacing_latency</item>
<item>@string/pacing_balanced</item>
<item>@string/pacing_balanced_alt</item>
<item>@string/pacing_smoothness</item>
</string-array>
<string-array name="video_frame_pacing_values" translatable="false">
<item>latency</item>
<item>balanced</item>
<item>cap-fps</item>
<item>smoothness</item>
</string-array>
</resources>
+9
View File
@@ -227,6 +227,14 @@
<string name="title_enable_post_stream_toast">Show latency message after streaming</string>
<string name="summary_enable_post_stream_toast">Display a latency information message after the stream ends</string>
<string name="category_help">Help</string>
<string name="title_setup_guide">Setup guide</string>
<string name="summary_setup_guide">View instructions on how to set up your gaming PC for streaming</string>
<string name="title_troubleshooting">Troubleshooting guide</string>
<string name="summary_troubleshooting">View tips for diagnosing and fixing common streaming issues</string>
<string name="title_privacy_policy">Privacy policy</string>
<string name="summary_privacy_policy">View Moonlight\'s privacy policy</string>
<!-- Array strings -->
<string name="resolution_360p">360p</string>
<string name="resolution_480p">480p</string>
@@ -252,5 +260,6 @@
<string name="summary_frame_pacing">Specify how to balance video latency and smoothness</string>
<string name="pacing_latency">Prefer lowest latency</string>
<string name="pacing_balanced">Balanced</string>
<string name="pacing_balanced_alt">Balanced with FPS limit</string>
<string name="pacing_smoothness">Prefer smoothest video (may significantly increase latency)</string>
</resources>
+15
View File
@@ -206,4 +206,19 @@
android:summary="@string/summary_enable_post_stream_toast"
android:defaultValue="false"/>
</PreferenceCategory>
<!--PreferenceCategory android:title="@string/category_help"
android:key="category_help">
<com.limelight.preferences.WebLauncherPreference
android:title="@string/title_setup_guide"
android:summary="@string/summary_setup_guide"
url="https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide"/>
<com.limelight.preferences.WebLauncherPreference
android:title="@string/title_troubleshooting"
android:summary="@string/summary_troubleshooting"
url="https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting"/>
<com.limelight.preferences.WebLauncherPreference
android:title="@string/title_privacy_policy"
android:summary="@string/summary_privacy_policy"
url="https://moonlight-stream.org/privacy.html"/>
</PreferenceCategory-->
</PreferenceScreen>
+2 -2
View File
@@ -2,13 +2,13 @@ version: 0.0.0.{build}
clone_depth: 1
image: Visual Studio 2019
image: Visual Studio 2022
before_build:
- 'git submodule update --init --recursive'
- 'mklink /D C:\android-sdk "C:\Program Files (x86)\Android\android-sdk"'
- 'set ANDROID_HOME=C:\android-sdk'
- 'set JAVA_HOME=C:\Program Files\Java\jdk11'
- 'set JAVA_HOME=C:\Program Files\Java\jdk17'
build_script:
- gradlew.bat build connectedCheck
+1 -1
View File
@@ -5,7 +5,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.android.tools.build:gradle:7.2.0'
}
}
@@ -0,0 +1,6 @@
- Improved frame pacing when streaming 60 FPS on 120 Hz devices
- Reduced power usage when streaming below maximum display refresh rate
- Reintroduced previous frame pacing behavior as "Balanced with FPS limit" option
- Rewrote PC address detection logic to better handle some network configurations
- Fixed simultaneous mouse and on-screen controller input
- Updated community contributed translations from Weblate
+1 -1
View File
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip