Compare commits

..
Author SHA1 Message Date
Cameron Gutman 41592b2ef4 WIP: Resolution dialog 2022-11-29 20:56:09 -06:00
24 changed files with 326 additions and 682 deletions
+2 -2
View File
@@ -9,8 +9,8 @@ android {
minSdk 16
targetSdk 33
versionName "10.11"
versionCode = 301
versionName "10.10"
versionCode = 298
// Generate native debug symbols to allow Google Play to symbolicate our native crashes
ndk.debugSymbolLevel = 'FULL'
+35 -64
View File
@@ -220,7 +220,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Enter landscape unless we're on a square screen
setPreferredOrientationForCurrentDisplay();
if (prefConfig.stretchVideo || shouldIgnoreInsetsForResolution(prefConfig.width, prefConfig.height)) {
if (prefConfig.stretchVideo || prefConfig.resolution.fullScreen) {
// Allow the activity to layout under notches if the fill-screen option
// was turned on by the user or it's a full-screen native resolution
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
@@ -456,7 +456,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
}
StreamConfiguration config = new StreamConfiguration.Builder()
.setResolution(prefConfig.width, prefConfig.height)
.setResolution(prefConfig.resolution.width, prefConfig.resolution.height)
.setLaunchRefreshRate(prefConfig.fps)
.setRefreshRate(chosenFrameRate)
.setApp(new NvApp(appName != null ? appName : "app", appId, appSupportsHdr))
@@ -551,12 +551,12 @@ public class Game extends Activity implements SurfaceHolder.Callback,
}
// For native resolution, we will lock the orientation to the one that matches the specified resolution
if (PreferenceConfiguration.isNativeResolution(prefConfig.width, prefConfig.height)) {
if (prefConfig.width > prefConfig.height) {
desiredOrientation = Configuration.ORIENTATION_LANDSCAPE;
if (prefConfig.resolution.type == PreferenceConfiguration.StreamResolution.ResolutionType.NATIVE) {
if (prefConfig.resolution.portrait) {
desiredOrientation = Configuration.ORIENTATION_PORTRAIT;
}
else {
desiredOrientation = Configuration.ORIENTATION_PORTRAIT;
desiredOrientation = Configuration.ORIENTATION_LANDSCAPE;
}
}
@@ -649,7 +649,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
private PictureInPictureParams getPictureInPictureParams(boolean autoEnter) {
PictureInPictureParams.Builder builder =
new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(prefConfig.width, prefConfig.height))
.setAspectRatio(new Rational(prefConfig.resolution.width, prefConfig.resolution.height))
.setSourceRectHint(new Rect(
streamView.getLeft(), streamView.getTop(),
streamView.getRight(), streamView.getBottom()));
@@ -771,26 +771,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
Math.round(refreshRate) % prefConfig.fps <= 3;
}
private boolean shouldIgnoreInsetsForResolution(int width, int height) {
// Never ignore insets for non-native resolutions
if (!PreferenceConfiguration.isNativeResolution(width, height)) {
return false;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Display display = getWindowManager().getDefaultDisplay();
for (Display.Mode candidate : display.getSupportedModes()) {
// Ignore insets if this is an exact match for the display resolution
if ((width == candidate.getPhysicalWidth() && height == candidate.getPhysicalHeight()) ||
(height == candidate.getPhysicalWidth() && width == candidate.getPhysicalHeight())) {
return true;
}
}
}
return false;
}
private boolean mayReduceRefreshRate() {
return prefConfig.framePacing == PreferenceConfiguration.FRAME_PACING_CAP_FPS ||
prefConfig.framePacing == PreferenceConfiguration.FRAME_PACING_MAX_SMOOTHNESS ||
@@ -805,7 +785,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// On M, we can explicitly set the optimal display mode
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
Display.Mode bestMode = display.getMode();
boolean isNativeResolutionStream = PreferenceConfiguration.isNativeResolution(prefConfig.width, prefConfig.height);
boolean refreshRateIsGood = isRefreshRateGoodMatch(bestMode.getRefreshRate());
boolean refreshRateIsEqual = isRefreshRateEqualMatch(bestMode.getRefreshRate());
@@ -813,13 +792,13 @@ public class Game extends Activity implements SurfaceHolder.Callback,
boolean refreshRateReduced = candidate.getRefreshRate() < bestMode.getRefreshRate();
boolean resolutionReduced = candidate.getPhysicalWidth() < bestMode.getPhysicalWidth() ||
candidate.getPhysicalHeight() < bestMode.getPhysicalHeight();
boolean resolutionFitsStream = candidate.getPhysicalWidth() >= prefConfig.width &&
candidate.getPhysicalHeight() >= prefConfig.height;
boolean resolutionFitsStream = candidate.getPhysicalWidth() >= prefConfig.resolution.width &&
candidate.getPhysicalHeight() >= prefConfig.resolution.height;
LimeLog.info("Examining display mode: "+candidate.getPhysicalWidth()+"x"+
candidate.getPhysicalHeight()+"x"+candidate.getRefreshRate());
if (candidate.getPhysicalWidth() > 4096 && prefConfig.width <= 4096) {
if (candidate.getPhysicalWidth() > 4096 && prefConfig.resolution.width <= 4096) {
// Avoid resolutions options above 4K to be safe
continue;
}
@@ -827,7 +806,8 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// On non-4K streams, we force the resolution to never change unless it's above
// 60 FPS, which may require a resolution reduction due to HDMI bandwidth limitations,
// or it's a native resolution stream.
if (prefConfig.width < 3840 && prefConfig.fps <= 60 && !isNativeResolutionStream) {
if (prefConfig.resolution.width < 3840 && prefConfig.fps <= 60 &&
prefConfig.resolution.type != PreferenceConfiguration.StreamResolution.ResolutionType.NATIVE) {
if (display.getMode().getPhysicalWidth() != candidate.getPhysicalWidth() ||
display.getMode().getPhysicalHeight() != candidate.getPhysicalHeight()) {
continue;
@@ -940,7 +920,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
display.getSize(screenSize);
double screenAspectRatio = ((double)screenSize.y) / screenSize.x;
double streamAspectRatio = ((double)prefConfig.height) / prefConfig.width;
double streamAspectRatio = ((double)prefConfig.resolution.height) / prefConfig.resolution.width;
if (Math.abs(screenAspectRatio - streamAspectRatio) < 0.001) {
LimeLog.info("Stream has compatible aspect ratio with output display");
aspectRatioMatch = true;
@@ -949,11 +929,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
if (prefConfig.stretchVideo || aspectRatioMatch) {
// Set the surface to the size of the video
streamView.getHolder().setFixedSize(prefConfig.width, prefConfig.height);
streamView.getHolder().setFixedSize(prefConfig.resolution.width, prefConfig.resolution.height);
}
else {
// Set the surface to scale based on the aspect ratio of the stream
streamView.setDesiredAspectRatio((double)prefConfig.width / (double)prefConfig.height);
streamView.setDesiredAspectRatio((double)prefConfig.resolution.width / (double)prefConfig.resolution.height);
}
if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION) ||
@@ -1126,25 +1106,17 @@ public class Game extends Activity implements SurfaceHolder.Callback,
finish();
}
private void setInputGrabState(boolean grab) {
// Grab/ungrab the mouse cursor
if (grab) {
inputCaptureProvider.enableCapture();
}
else {
inputCaptureProvider.disableCapture();
}
// Grab/ungrab system keyboard shortcuts
setMetaKeyCaptureState(grab);
grabbedInput = grab;
}
private final Runnable toggleGrab = new Runnable() {
@Override
public void run() {
setInputGrabState(!grabbedInput);
if (grabbedInput) {
inputCaptureProvider.disableCapture();
}
else {
inputCaptureProvider.enableCapture();
}
grabbedInput = !grabbedInput;
}
};
@@ -1164,10 +1136,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
androidKeyCode == KeyEvent.KEYCODE_ALT_RIGHT) {
modifierMask = KeyboardPacket.MODIFIER_ALT;
}
else if (androidKeyCode == KeyEvent.KEYCODE_META_LEFT ||
androidKeyCode == KeyEvent.KEYCODE_META_RIGHT) {
modifierMask = KeyboardPacket.MODIFIER_META;
}
if (down) {
this.modifierFlags |= modifierMask;
@@ -1176,10 +1144,10 @@ public class Game extends Activity implements SurfaceHolder.Callback,
this.modifierFlags &= ~modifierMask;
}
// Check if Ctrl+Alt+Shift+Z is pressed
// Check if Ctrl+Shift+Z is pressed
if (androidKeyCode == KeyEvent.KEYCODE_Z &&
(modifierFlags & (KeyboardPacket.MODIFIER_CTRL | KeyboardPacket.MODIFIER_ALT | KeyboardPacket.MODIFIER_SHIFT)) ==
(KeyboardPacket.MODIFIER_CTRL | KeyboardPacket.MODIFIER_ALT | KeyboardPacket.MODIFIER_SHIFT))
(modifierFlags & (KeyboardPacket.MODIFIER_CTRL | KeyboardPacket.MODIFIER_SHIFT)) ==
(KeyboardPacket.MODIFIER_CTRL | KeyboardPacket.MODIFIER_SHIFT))
{
if (down) {
// Now that we've pressed the magic combo
@@ -1230,9 +1198,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
if (event.isAltPressed()) {
modifier |= KeyboardPacket.MODIFIER_ALT;
}
if (event.isMetaPressed()) {
modifier |= KeyboardPacket.MODIFIER_META;
}
return modifier;
}
@@ -1896,8 +1861,11 @@ public class Game extends Activity implements SurfaceHolder.Callback,
// Let the display go to sleep now
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Ungrab input
setInputGrabState(false);
// Enable cursor visibility again
inputCaptureProvider.disableCapture();
// Disable meta key capture
setMetaKeyCaptureState(false);
if (!displayedFailureDialog) {
displayedFailureDialog = true;
@@ -2007,13 +1975,16 @@ public class Game extends Activity implements SurfaceHolder.Callback,
h.postDelayed(new Runnable() {
@Override
public void run() {
setInputGrabState(true);
inputCaptureProvider.enableCapture();
}
}, 500);
// Keep the display on
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Enable meta key capture
setMetaKeyCaptureState(true);
// Update GameManager state to indicate we're in game
UiHelper.notifyStreamConnected(Game.this);
@@ -134,7 +134,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private boolean decoderCanMeetPerformancePoint(MediaCodecInfo.VideoCapabilities caps, PreferenceConfiguration prefs) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
MediaCodecInfo.VideoCapabilities.PerformancePoint targetPerfPoint = new MediaCodecInfo.VideoCapabilities.PerformancePoint(prefs.width, prefs.height, prefs.fps);
MediaCodecInfo.VideoCapabilities.PerformancePoint targetPerfPoint = new MediaCodecInfo.VideoCapabilities.PerformancePoint(prefs.resolution.width, prefs.resolution.height, prefs.fps);
List<MediaCodecInfo.VideoCapabilities.PerformancePoint> perfPoints = caps.getSupportedPerformancePoints();
if (perfPoints != null) {
for (MediaCodecInfo.VideoCapabilities.PerformancePoint perfPoint : perfPoints) {
@@ -155,7 +155,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
try {
// We'll ask the decoder what it can do for us at this resolution and see if our
// requested frame rate falls below or inside the range of achievable frame rates.
Range<Double> fpsRange = caps.getAchievableFrameRatesFor(prefs.width, prefs.height);
Range<Double> fpsRange = caps.getAchievableFrameRatesFor(prefs.resolution.width, prefs.resolution.height);
if (fpsRange != null) {
return prefs.fps <= fpsRange.getUpper();
}
@@ -170,7 +170,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
// As a last resort, we will use areSizeAndRateSupported() which is explicitly NOT a
// performance metric, but it can work at least for the purpose of determining if
// the codec is going to die when given a stream with the specified settings.
return caps.areSizeAndRateSupported(prefs.width, prefs.height, prefs.fps);
return caps.areSizeAndRateSupported(prefs.resolution.width, prefs.resolution.height, prefs.fps);
}
private boolean decoderCanMeetPerformancePointWithHevcAndNotAvc(MediaCodecInfo avcDecoderInfo, MediaCodecInfo hevcDecoderInfo, PreferenceConfiguration prefs) {
@@ -211,7 +211,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
LimeLog.info("Forcing HEVC enabled for HDR streaming");
}
// > 4K streaming also requires HEVC, so force it on there too.
else if (prefs.width > 4096 || prefs.height > 4096) {
else if (prefs.resolution.width > 4096 || prefs.resolution.height > 4096) {
LimeLog.info("Forcing HEVC enabled for over 4K streaming");
}
// Use HEVC if the H.264 decoder is unable to meet the performance point
@@ -271,7 +271,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
int hevcOptimalSlicesPerFrame = 0;
if (avcDecoder != null) {
directSubmit = MediaCodecHelper.decoderCanDirectSubmit(avcDecoder.getName());
refFrameInvalidationAvc = MediaCodecHelper.decoderSupportsRefFrameInvalidationAvc(avcDecoder.getName(), prefs.height);
refFrameInvalidationAvc = MediaCodecHelper.decoderSupportsRefFrameInvalidationAvc(avcDecoder.getName(), prefs.resolution.height);
avcOptimalSlicesPerFrame = MediaCodecHelper.getDecoderOptimalSlicesPerFrame(avcDecoder.getName());
if (directSubmit) {
@@ -328,28 +328,11 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
}
public int getPreferredColorSpace() {
// Default to Rec 709 which is probably better supported on modern devices.
//
// We are sticking to Rec 601 on older devices unless the device has an HEVC decoder
// to avoid possible regressions (and they are < 5% of installed devices). If we have
// an HEVC decoder, we will use Rec 709 (even for H.264) since we can't choose a
// colorspace by codec (and it's probably safe to say a SoC with HEVC decoding is
// plenty modern enough to handle H.264 VUI colorspace info).
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O || hevcDecoder != null) {
return MoonBridge.COLORSPACE_REC_709;
}
else {
return MoonBridge.COLORSPACE_REC_601;
}
return MoonBridge.COLORSPACE_REC_601;
}
public int getPreferredColorRange() {
if (prefs.fullRange) {
return MoonBridge.COLOR_RANGE_FULL;
}
else {
return MoonBridge.COLOR_RANGE_LIMITED;
}
return MoonBridge.COLOR_RANGE_LIMITED;
}
public void notifyVideoForeground() {
@@ -1320,10 +1303,9 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements C
sps.numRefFrames = 1;
}
// GFE 2.5.11 changed the SPS to add additional extensions. Some devices don't like these
// so we remove them here on old devices unless these devices also support HEVC.
// See getPreferredColorSpace() for further information.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O && hevcDecoder == null && sps.vuiParams != null) {
// GFE 2.5.11 changed the SPS to add additional extensions
// Some devices don't like these so we remove them here on old devices.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O && sps.vuiParams != null) {
sps.vuiParams.videoSignalTypePresentFlag = false;
sps.vuiParams.colourDescriptionPresentFlag = false;
sps.vuiParams.chromaLocInfoPresentFlag = false;
@@ -3,6 +3,7 @@ package com.limelight.binding.video;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
@@ -77,6 +78,12 @@ public class MediaCodecHelper {
refFrameInvalidationHevcPrefixes.add("omx.exynos");
refFrameInvalidationHevcPrefixes.add("c2.exynos");
// The Chromecast with Google TV 4K works well with HEVC RFI since we also use the
// vendor.low-latency.enable option.
if (Build.DEVICE.equalsIgnoreCase("sabrina")) {
refFrameInvalidationHevcPrefixes.add("omx.amlogic");
}
// Qualcomm and NVIDIA may be added at runtime
}
@@ -177,9 +184,6 @@ public class MediaCodecHelper {
// vendor.low-latency.enable. We will still use HEVC if decoderCanMeetPerformancePointWithHevcAndNotAvc()
// determines it's the only way to meet the performance requirements.
//
// With the Android 12 update, Sabrina now uses HEVC (with RFI) based upon FEATURE_LowLatency
// support, which provides equivalent latency to H.264 now.
//
// FIXME: Should we do this for all Amlogic S905X SoCs?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && !Build.DEVICE.equalsIgnoreCase("sabrina")) {
whitelistedHevcDecoders.add("omx.amlogic");
@@ -711,12 +715,19 @@ public class MediaCodecHelper {
// HEVC decoder present is fast and modern enough for streaming.
//
// [5.3/H-1-1] MUST NOT drop more than 2 frames in 10 seconds (i.e less than 0.333 percent frame drop) for a 1080p 60 fps video session under load.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
LimeLog.info("Media performance class: " + Build.VERSION.MEDIA_PERFORMANCE_CLASS);
if (Build.VERSION.MEDIA_PERFORMANCE_CLASS >= Build.VERSION_CODES.S) {
LimeLog.info("Allowing HEVC based on media performance class");
//
// NB: We use reflection here because this field seems to be absent on Amazon Fire OS devices
try {
Field mediaClassField = Build.VERSION.class.getDeclaredField("MEDIA_PERFORMANCE_CLASS");
int mediaClass = mediaClassField.getInt(null);
if (mediaClass >= Build.VERSION_CODES.S) {
LimeLog.info("Allowing HEVC based on media performance class: " + mediaClass);
return true;
}
} catch (NoSuchFieldException e) {
LimeLog.info("Build.VERSION.MEDIA_PERFORMANCE_CLASS not present");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
// If the decoder supports FEATURE_LowLatency, we will assume it is fast and modern enough
@@ -64,8 +64,6 @@ public class ComputerManagerService extends Service {
private boolean pollingActive = false;
private final Lock defaultNetworkLock = new ReentrantLock();
private ConnectivityManager.NetworkCallback networkCallback;
private DiscoveryService.DiscoveryBinder discoveryBinder;
private final ServiceConnection discoveryServiceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
@@ -555,8 +553,7 @@ public class ComputerManagerService extends Service {
// If the current address's port number matches the active address's port number, we can also assume
// the HTTPS port will also match. This assumption is currently safe because Sunshine sets all ports
// as offsets from the base HTTP port and doesn't allow custom HttpsPort responses for WAN vs LAN.
boolean portMatchesActiveAddress = details.state == ComputerDetails.State.ONLINE &&
details.activeAddress != null && address.port == details.activeAddress.port;
boolean portMatchesActiveAddress = details.activeAddress != null && address.port == details.activeAddress.port;
NvHTTP http = new NvHTTP(address, portMatchesActiveAddress ? details.httpsPort : 0, idManager.getUniqueId(), details.serverCert,
PlatformBinding.getCryptoProvider(ComputerManagerService.this));
@@ -746,49 +743,10 @@ public class ComputerManagerService extends Service {
}
releaseLocalDatabaseReference();
// Monitor for network changes to invalidate our PC state
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
LimeLog.info("Resetting PC state for new available network");
synchronized (pollingTuples) {
for (PollingTuple tuple : pollingTuples) {
tuple.computer.state = ComputerDetails.State.UNKNOWN;
if (listener != null) {
listener.notifyComputerUpdated(tuple.computer);
}
}
}
}
@Override
public void onLost(Network network) {
LimeLog.info("Offlining PCs due to network loss");
synchronized (pollingTuples) {
for (PollingTuple tuple : pollingTuples) {
tuple.computer.state = ComputerDetails.State.OFFLINE;
if (listener != null) {
listener.notifyComputerUpdated(tuple.computer);
}
}
}
}
};
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
connMgr.registerDefaultNetworkCallback(networkCallback);
}
}
@Override
public void onDestroy() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
connMgr.unregisterNetworkCallback(networkCallback);
}
if (discoveryBinder != null) {
// Unbind from the discovery service
unbindService(discoveryServiceConnection);
@@ -20,11 +20,6 @@ public class ComputerDetails {
throw new IllegalArgumentException("Invalid port");
}
// If this was an escaped IPv6 address, remove the brackets
if (address.startsWith("[") && address.endsWith("]")) {
address = address.substring(1, address.length() - 1);
}
this.address = address;
this.port = port;
}
@@ -45,14 +40,7 @@ public class ComputerDetails {
}
public String toString() {
if (address.contains(":")) {
// IPv6
return "[" + address + "]:" + port;
}
else {
// IPv4 and hostnames
return address + ":" + port;
}
return address + ":" + port;
}
}
@@ -7,5 +7,4 @@ public class KeyboardPacket {
public static final byte MODIFIER_SHIFT = 0x01;
public static final byte MODIFIER_CTRL = 0x02;
public static final byte MODIFIER_ALT = 0x04;
public static final byte MODIFIER_META = 0x08;
}
}
@@ -98,31 +98,8 @@ public class AddComputerManually extends Activity {
}
}
private URI parseRawUserInputToUri(String rawUserInput) {
try {
// Try adding a scheme and parsing the remaining input.
// This handles input like 127.0.0.1:47989, [::1], [::1]:47989, and 127.0.0.1.
URI uri = new URI("moonlight://" + rawUserInput);
if (uri.getHost() != null && !uri.getHost().isEmpty()) {
return uri;
}
} catch (URISyntaxException ignored) {}
try {
// Attempt to escape the input as an IPv6 literal.
// This handles input like ::1.
URI uri = new URI("moonlight://[" + rawUserInput + "]");
if (uri.getHost() != null && !uri.getHost().isEmpty()) {
return uri;
}
} catch (URISyntaxException ignored) {}
return null;
}
private void doAddPc(String rawUserInput) throws InterruptedException {
boolean wrongSiteLocal = false;
boolean invalidInput = false;
boolean success;
int portTestResult;
@@ -132,26 +109,26 @@ public class AddComputerManually extends Activity {
try {
ComputerDetails details = new ComputerDetails();
// Check if we parsed a host address successfully
URI uri = parseRawUserInputToUri(rawUserInput);
if (uri != null && uri.getHost() != null && !uri.getHost().isEmpty()) {
String host = uri.getHost();
int port = uri.getPort();
// Use URI-style parsing for the host address input
URI uri = new URI("moonlight://" + rawUserInput);
// If a port was not specified, use the default
if (port == -1) {
port = NvHTTP.DEFAULT_HTTP_PORT;
}
String host = uri.getHost();
int port = uri.getPort();
details.manualAddress = new ComputerDetails.AddressTuple(host, port);
success = managerBinder.addComputerBlocking(details);
if (!success){
wrongSiteLocal = isWrongSubnetSiteLocalAddress(host);
}
} else {
// Invalid user input
success = false;
invalidInput = true;
// URI allows empty hosts, but we don't want that
if (host == null || host.isEmpty()) {
throw new URISyntaxException(rawUserInput, "Host failed to parse");
}
// If a port was not specified, use the default
if (port == -1) {
port = NvHTTP.DEFAULT_HTTP_PORT;
}
details.manualAddress = new ComputerDetails.AddressTuple(host, port);
success = managerBinder.addComputerBlocking(details);
if (!success){
wrongSiteLocal = isWrongSubnetSiteLocalAddress(host);
}
} catch (InterruptedException e) {
// Propagate the InterruptedException to the caller for proper handling
@@ -162,11 +139,13 @@ public class AddComputerManually extends Activity {
// https://github.com/square/okhttp/blob/okhttp_27/okhttp/src/main/java/com/squareup/okhttp/HttpUrl.java#L705
e.printStackTrace();
success = false;
invalidInput = true;
} catch (URISyntaxException e) {
e.printStackTrace();
success = false;
}
// Keep the SpinnerDialog open while testing connectivity
if (!success && !wrongSiteLocal && !invalidInput) {
if (!success && !wrongSiteLocal) {
// Run the test before dismissing the spinner because it can take a few seconds.
portTestResult = MoonBridge.testClientConnectivity(ServerHelper.CONNECTION_TEST_SERVER, 443,
MoonBridge.ML_PORT_FLAG_TCP_47984 | MoonBridge.ML_PORT_FLAG_TCP_47989);
@@ -177,10 +156,7 @@ public class AddComputerManually extends Activity {
dialog.dismiss();
if (invalidInput) {
Dialog.displayDialog(this, getResources().getString(R.string.conn_error_title), getResources().getString(R.string.addpc_unknown_host), false);
}
else if (wrongSiteLocal) {
if (wrongSiteLocal) {
Dialog.displayDialog(this, getResources().getString(R.string.conn_error_title), getResources().getString(R.string.addpc_wrong_sitelocal), false);
}
else if (!success) {
@@ -48,7 +48,6 @@ public class PreferenceConfiguration {
private static final String ABSOLUTE_MOUSE_MODE_PREF_STRING = "checkbox_absolute_mouse_mode";
private static final String ENABLE_AUDIO_FX_PREF_STRING = "checkbox_enable_audiofx";
private static final String REDUCE_REFRESH_RATE_PREF_STRING = "checkbox_reduce_refresh_rate";
private static final String FULL_RANGE_PREF_STRING = "checkbox_full_range";
static final String DEFAULT_RESOLUTION = "1280x720";
static final String DEFAULT_FPS = "60";
@@ -81,7 +80,6 @@ public class PreferenceConfiguration {
private static final boolean DEFAULT_ABSOLUTE_MOUSE_MODE = false;
private static final boolean DEFAULT_ENABLE_AUDIO_FX = false;
private static final boolean DEFAULT_REDUCE_REFRESH_RATE = false;
private static final boolean DEFAULT_FULL_RANGE = false;
public static final int FORCE_H265_ON = -1;
public static final int AUTOSELECT_H265 = 0;
@@ -92,15 +90,15 @@ public class PreferenceConfiguration {
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";
public static final String RES_720P = "1280x720";
public static final String RES_1080P = "1920x1080";
public static final String RES_1440P = "2560x1440";
public static final String RES_4K = "3840x2160";
public static final String RES_NATIVE = "Native";
public static final String RES_360P = "s_640x360";
public static final String RES_480P = "s_854x480";
public static final String RES_720P = "s_1280x720";
public static final String RES_1080P = "s_1920x1080";
public static final String RES_1440P = "s_2560x1440";
public static final String RES_4K = "s_3840x2160";
public int width, height, fps;
public StreamResolution resolution;
public int fps;
public int bitrate;
public int videoFormat;
public int deadzonePercentage;
@@ -126,9 +124,10 @@ public class PreferenceConfiguration {
public boolean absoluteMouseMode;
public boolean enableAudioFx;
public boolean reduceRefreshRate;
public boolean fullRange;
public static boolean isNativeResolution(int width, int height) {
// This is used only for migration to the new type code format of resolution strings
// It doesn't properly handle custom resolutions!
private static boolean legacyIsNativeResolution(int width, int height) {
// It's not a native resolution if it matches an existing resolution option
if (width == 640 && height == 360) {
return false;
@@ -178,59 +177,47 @@ public class PreferenceConfiguration {
}
private static String convertFromLegacyResolutionString(String resString) {
if (resString.equalsIgnoreCase("360p")) {
return RES_360P;
if (!resString.contains("x")) {
// Convert from hardcoded strings to strings with dimensions embedded
if (resString.equalsIgnoreCase("360p")) {
return RES_360P;
}
else if (resString.equalsIgnoreCase("480p")) {
return RES_480P;
}
else if (resString.equalsIgnoreCase("720p")) {
return RES_720P;
}
else if (resString.equalsIgnoreCase("1080p")) {
return RES_1080P;
}
else if (resString.equalsIgnoreCase("1440p")) {
return RES_1440P;
}
else if (resString.equalsIgnoreCase("4K")) {
return RES_4K;
}
else {
// Should be unreachable
return RES_720P;
}
}
else if (resString.equalsIgnoreCase("480p")) {
return RES_480P;
}
else if (resString.equalsIgnoreCase("720p")) {
return RES_720P;
}
else if (resString.equalsIgnoreCase("1080p")) {
return RES_1080P;
}
else if (resString.equalsIgnoreCase("1440p")) {
return RES_1440P;
}
else if (resString.equalsIgnoreCase("4K")) {
return RES_4K;
else if (Character.isDigit(resString.charAt(0))) {
// Convert to type code prefix format
String[] dims = resString.split("x");
int width = Integer.parseInt(dims[0]);
int height = Integer.parseInt(dims[1]);
return new StreamResolution(width, height,
legacyIsNativeResolution(width, height) ? StreamResolution.ResolutionType.NATIVE : StreamResolution.ResolutionType.STANDARD)
.toPrefString();
}
else {
// Should be unreachable
return RES_720P;
}
}
private static int getWidthFromResolutionString(String resString) {
return Integer.parseInt(resString.split("x")[0]);
}
private static int getHeightFromResolutionString(String resString) {
return Integer.parseInt(resString.split("x")[1]);
}
private static String getResolutionString(int width, int height) {
switch (height) {
case 360:
return RES_360P;
case 480:
return RES_480P;
default:
case 720:
return RES_720P;
case 1080:
return RES_1080P;
case 1440:
return RES_1440P;
case 2160:
return RES_4K;
return resString;
}
}
public static int getDefaultBitrate(String resString, String fpsString) {
int width = getWidthFromResolutionString(resString);
int height = getHeightFromResolutionString(resString);
StreamResolution res = new StreamResolution(resString);
int fps = Integer.parseInt(fpsString);
// This table prefers 16:10 resolutions because they are
@@ -241,23 +228,23 @@ public class PreferenceConfiguration {
// This logic is shamelessly stolen from Moonlight Qt:
// https://github.com/moonlight-stream/moonlight-qt/blob/master/app/settings/streamingpreferences.cpp
if (width * height <= 640 * 360) {
if (res.width * res.height <= 640 * 360) {
return (int)(1000 * (fps / 30.0));
}
else if (width * height <= 854 * 480) {
else if (res.width * res.height <= 854 * 480) {
return (int)(1500 * (fps / 30.0));
}
// This covers 1280x720 and 1280x800 too
else if (width * height <= 1366 * 768) {
else if (res.width * res.height <= 1366 * 768) {
return (int)(5000 * (fps / 30.0));
}
else if (width * height <= 1920 * 1200) {
else if (res.width * res.height <= 1920 * 1200) {
return (int)(10000 * (fps / 30.0));
}
else if (width * height <= 2560 * 1600) {
else if (res.width * res.height <= 2560 * 1600) {
return (int)(20000 * (fps / 30.0));
}
else /* if (width * height <= 3840 * 2160) */ {
else /* if (res.width * res.height <= 3840 * 2160) */ {
return (int)(40000 * (fps / 30.0));
}
}
@@ -351,7 +338,6 @@ public class PreferenceConfiguration {
.remove(VIDEO_FORMAT_PREF_STRING)
.remove(ENABLE_HDR_PREF_STRING)
.remove(UNLOCK_FPS_STRING)
.remove(FULL_RANGE_PREF_STRING)
.apply();
}
@@ -385,55 +371,46 @@ public class PreferenceConfiguration {
String str = prefs.getString(LEGACY_RES_FPS_PREF_STRING, null);
if (str != null) {
if (str.equals("360p30")) {
config.width = 640;
config.height = 360;
config.resolution = new StreamResolution(640, 360, StreamResolution.ResolutionType.STANDARD);
config.fps = 30;
}
else if (str.equals("360p60")) {
config.width = 640;
config.height = 360;
config.resolution = new StreamResolution(640, 360, StreamResolution.ResolutionType.STANDARD);
config.fps = 60;
}
else if (str.equals("720p30")) {
config.width = 1280;
config.height = 720;
config.resolution = new StreamResolution(1280, 720, StreamResolution.ResolutionType.STANDARD);
config.fps = 30;
}
else if (str.equals("720p60")) {
config.width = 1280;
config.height = 720;
config.resolution = new StreamResolution(1280, 720, StreamResolution.ResolutionType.STANDARD);
config.fps = 60;
}
else if (str.equals("1080p30")) {
config.width = 1920;
config.height = 1080;
config.resolution = new StreamResolution(1920, 1080, StreamResolution.ResolutionType.STANDARD);
config.fps = 30;
}
else if (str.equals("1080p60")) {
config.width = 1920;
config.height = 1080;
config.resolution = new StreamResolution(1920, 1080, StreamResolution.ResolutionType.STANDARD);
config.fps = 60;
}
else if (str.equals("4K30")) {
config.width = 3840;
config.height = 2160;
config.resolution = new StreamResolution(3840, 2160, StreamResolution.ResolutionType.STANDARD);
config.fps = 30;
}
else if (str.equals("4K60")) {
config.width = 3840;
config.height = 2160;
config.resolution = new StreamResolution(3840, 2160, StreamResolution.ResolutionType.STANDARD);
config.fps = 60;
}
else {
// Should never get here
config.width = 1280;
config.height = 720;
config.resolution = new StreamResolution(1280, 720, StreamResolution.ResolutionType.STANDARD);
config.fps = 60;
}
prefs.edit()
.remove(LEGACY_RES_FPS_PREF_STRING)
.putString(RESOLUTION_PREF_STRING, getResolutionString(config.width, config.height))
.putString(RESOLUTION_PREF_STRING, config.resolution.toPrefString())
.putString(FPS_PREF_STRING, ""+config.fps)
.apply();
}
@@ -442,13 +419,12 @@ public class PreferenceConfiguration {
String resStr = prefs.getString(RESOLUTION_PREF_STRING, PreferenceConfiguration.DEFAULT_RESOLUTION);
// Convert legacy resolution strings to the new style
if (!resStr.contains("x")) {
if (Character.isDigit(resStr.charAt(0)) || !resStr.contains("x")) {
resStr = PreferenceConfiguration.convertFromLegacyResolutionString(resStr);
prefs.edit().putString(RESOLUTION_PREF_STRING, resStr).apply();
}
config.width = PreferenceConfiguration.getWidthFromResolutionString(resStr);
config.height = PreferenceConfiguration.getHeightFromResolutionString(resStr);
config.resolution = new StreamResolution(resStr);
config.fps = Integer.parseInt(prefs.getString(FPS_PREF_STRING, PreferenceConfiguration.DEFAULT_FPS));
}
@@ -509,8 +485,115 @@ public class PreferenceConfiguration {
config.absoluteMouseMode = prefs.getBoolean(ABSOLUTE_MOUSE_MODE_PREF_STRING, DEFAULT_ABSOLUTE_MOUSE_MODE);
config.enableAudioFx = prefs.getBoolean(ENABLE_AUDIO_FX_PREF_STRING, DEFAULT_ENABLE_AUDIO_FX);
config.reduceRefreshRate = prefs.getBoolean(REDUCE_REFRESH_RATE_PREF_STRING, DEFAULT_REDUCE_REFRESH_RATE);
config.fullRange = prefs.getBoolean(FULL_RANGE_PREF_STRING, DEFAULT_FULL_RANGE);
return config;
}
public static class StreamResolution {
public int width;
public int height;
public ResolutionType type;
public boolean portrait;
public boolean fullScreen;
private static final char RES_START_DELIMITER = '_';
private static final char RES_DIM_DELIMITER = 'x';
private static final char TYPE_CODE_STANDARD = 's';
private static final char TYPE_CODE_NATIVE = 'n';
private static final char OPTION_CODE_PORTRAIT = 'p';
private static final char OPTION_CODE_FULL_SCREEN = 'f';
public enum ResolutionType {
STANDARD,
NATIVE
}
private StreamResolution(int width, int height, ResolutionType type) {
this.width = width;
this.height = height;
this.type = type;
// Just guess for the options, since we don't know for sure
this.portrait = height > width;
this.fullScreen = false;
}
public StreamResolution(int width, int height, ResolutionType type, boolean portrait, boolean fullScreen) {
this.width = width;
this.height = height;
this.type = type;
this.portrait = portrait;
this.fullScreen = fullScreen;
}
StreamResolution(String resString) {
// Type code is the first character in the string
switch (resString.charAt(0)) {
case TYPE_CODE_NATIVE:
this.type = StreamResolution.ResolutionType.NATIVE;
break;
case TYPE_CODE_STANDARD:
this.type = StreamResolution.ResolutionType.STANDARD;
break;
default:
throw new IllegalArgumentException("Invalid type code: " + resString.charAt(0));
}
// Parse options until we reach the resolution start delimiter
int currentIndex = 1;
while (resString.charAt(currentIndex) != RES_START_DELIMITER) {
switch (resString.charAt(currentIndex)) {
case OPTION_CODE_PORTRAIT:
portrait = true;
break;
case OPTION_CODE_FULL_SCREEN:
fullScreen = true;
break;
default:
throw new IllegalArgumentException("Invalid option code: " + resString.charAt(currentIndex));
}
currentIndex++;
}
// Skip the type code before splitting
String[] dims = resString.substring(currentIndex).split(""+RES_DIM_DELIMITER);
this.width = Integer.parseInt(dims[0]);
this.height = Integer.parseInt(dims[1]);
}
public String toPrefString() {
String str = "";
// Start with the type code
switch (type) {
case NATIVE:
str += TYPE_CODE_NATIVE;
break;
case STANDARD:
str += TYPE_CODE_STANDARD;
break;
default:
throw new IllegalArgumentException("Invalid type: "+type);
}
// Now any option codes that may apply
if (portrait) {
str += OPTION_CODE_PORTRAIT;
}
if (fullScreen) {
str += OPTION_CODE_FULL_SCREEN;
}
// And finally the dimensions
str += RES_START_DELIMITER;
str += width;
str += RES_DIM_DELIMITER;
str += height;
return str;
}
}
}
@@ -122,44 +122,49 @@ public class StreamSettings extends Activity {
}
public static class SettingsFragment extends PreferenceFragment {
private int nativeResolutionStartIndex = Integer.MAX_VALUE;
private void setValue(String preferenceKey, String value) {
ListPreference pref = (ListPreference) findPreference(preferenceKey);
pref.setValue(value);
}
private void addNativeResolutionEntry(int nativeWidth, int nativeHeight, boolean insetsRemoved, boolean portrait) {
private void addResolutionEntry(int width, int height, PreferenceConfiguration.StreamResolution.ResolutionType type,
boolean insetsRemoved, boolean portrait) {
ListPreference pref = (ListPreference) findPreference(PreferenceConfiguration.RESOLUTION_PREF_STRING);
PreferenceConfiguration.StreamResolution newRes =
new PreferenceConfiguration.StreamResolution(width, height, type, portrait, insetsRemoved);
String newName;
if (insetsRemoved) {
newName = getResources().getString(R.string.resolution_prefix_native_fullscreen);
}
else {
newName = getResources().getString(R.string.resolution_prefix_native);
}
if (PreferenceConfiguration.isSquarishScreen(nativeWidth, nativeHeight)) {
if (portrait) {
newName += " " + getResources().getString(R.string.resolution_prefix_native_portrait);
if (type == PreferenceConfiguration.StreamResolution.ResolutionType.NATIVE) {
if (insetsRemoved) {
newName = getResources().getString(R.string.resolution_prefix_native_fullscreen);
}
else {
newName += " " + getResources().getString(R.string.resolution_prefix_native_landscape);
newName = getResources().getString(R.string.resolution_prefix_native);
}
if (PreferenceConfiguration.isSquarishScreen(width, height)) {
if (portrait) {
newName += " " + getResources().getString(R.string.resolution_prefix_native_portrait);
}
else {
newName += " " + getResources().getString(R.string.resolution_prefix_native_landscape);
}
}
}
else {
newName = null;
}
newName += " ("+nativeWidth+"x"+nativeHeight+")";
String newValue = nativeWidth+"x"+nativeHeight;
newName += " ("+width+"x"+height+")";
CharSequence[] values = pref.getEntryValues();
// Check if the native resolution is already present
// Check if the new resolution is already present
for (CharSequence value : values) {
if (newValue.equals(value.toString())) {
PreferenceConfiguration.StreamResolution existingResolution = new PreferenceConfiguration.StreamResolution(value.toString());
if (existingResolution.width == newRes.width && existingResolution.height == newRes.height) {
// It is present in the default list, so don't add it again
return;
}
@@ -168,23 +173,23 @@ public class StreamSettings extends Activity {
CharSequence[] newEntries = Arrays.copyOf(pref.getEntries(), pref.getEntries().length + 1);
CharSequence[] newValues = Arrays.copyOf(values, values.length + 1);
// Add the new native option
// Add the new resolution option
newEntries[newEntries.length - 1] = newName;
newValues[newValues.length - 1] = newValue;
newValues[newValues.length - 1] = newRes.toPrefString();
pref.setEntries(newEntries);
pref.setEntryValues(newValues);
if (newValues.length - 1 < nativeResolutionStartIndex) {
nativeResolutionStartIndex = newValues.length - 1;
}
}
private void addNativeResolutionEntries(int nativeWidth, int nativeHeight, boolean insetsRemoved) {
if (PreferenceConfiguration.isSquarishScreen(nativeWidth, nativeHeight)) {
addNativeResolutionEntry(nativeHeight, nativeWidth, insetsRemoved, true);
addResolutionEntry(nativeHeight, nativeWidth,
PreferenceConfiguration.StreamResolution.ResolutionType.NATIVE,
insetsRemoved, true);
}
addNativeResolutionEntry(nativeWidth, nativeHeight, insetsRemoved, false);
addResolutionEntry(nativeWidth, nativeHeight,
PreferenceConfiguration.StreamResolution.ResolutionType.NATIVE,
insetsRemoved, false);
}
private void removeValue(String preferenceKey, String value, Runnable onMatched) {
@@ -608,20 +613,10 @@ public class StreamSettings extends Activity {
public boolean onPreferenceChange(Preference preference, Object newValue) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SettingsFragment.this.getActivity());
String valueStr = (String) newValue;
// Detect if this value is the native resolution option
CharSequence[] values = ((ListPreference)preference).getEntryValues();
boolean isNativeRes = true;
for (int i = 0; i < values.length; i++) {
// Look for a match prior to the start of the native resolution entries
if (valueStr.equals(values[i].toString()) && i < nativeResolutionStartIndex) {
isNativeRes = false;
break;
}
}
PreferenceConfiguration.StreamResolution resolution = new PreferenceConfiguration.StreamResolution(valueStr);
// If this is native resolution, show the warning dialog
if (isNativeRes) {
if (resolution.type == PreferenceConfiguration.StreamResolution.ResolutionType.NATIVE) {
Dialog.displayDialog(getActivity(),
getResources().getString(R.string.title_native_res_dialog),
getResources().getString(R.string.text_native_res_dialog),
+1 -250
View File
@@ -1,251 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="conn_establishing_title">Připojování</string>
<string name="conn_metered">Varování: Vaše aktivní připojení je měřené!</string>
<string name="conn_error_msg">Spouštění se nezdařilo</string>
<string name="conn_client_latency_hw">zpoždění hardwarového dekodéru:</string>
<string name="conn_terminated_title">Spojení ukončeno</string>
<string name="resolution_prefix_native_fullscreen">Nativní celá obrazovka</string>
<string name="summary_checkbox_enable_audiofx">Umožňuje fungování zvukových efektů během streamování, ale může zvýšit zpoždění zvuku</string>
<string name="early_termination_error">Na hostitelském PC se něco pokazilo při spouštění streamu.
\n
\nUjistěte se, že na hostitelském počítači neběží žádný obsah chráněný DRM. Můžete také zkusit restartovat hostitelský PC.
\n
\nPokud problém přetrvává, zkuste přeinstalovat ovladače GPU a GeForce Experience.</string>
<string name="wol_waking_pc">Probouzení PC…</string>
<string name="nettest_text_success">Vypadá to, že vaše síť Moonlight neblokuje. Pokud máte i tak potíže s připojením, zkontrolujte nastavení firewallu vašeho PC.
\n
\nPokud se pokoušíte streamovat po internetu, nainstalujte si na svůj počítač Moonlight Internet Hosting Tool a spusťte přiložený program Internet Streaming Tester pro kontrolu vašeho připojení k Internetu.</string>
<string name="error_unknown_host">Nezdařilo se zjistit hostitele</string>
<string name="nettest_text_waiting">Moonlight testuje vaše síťové připojení, aby zjistil, jestli je NVIDIA GameStream zablokován.
\n
\nTo může chvilku zabrat…</string>
<string name="nettest_title_waiting">Testování připojení k síti</string>
<string name="pairing">Párování…</string>
<string name="pair_pc_offline">Počítač je offline</string>
<string name="unpairing">Rušení párování…</string>
<string name="unpair_success">Párování úspěšně zrušeno</string>
<string name="unpair_error">Zařízení nebylo spárováno</string>
<string name="error_manager_not_running">Služba ComputerManager neběží. Vyčkejte prosím chvíli nebo restartujte aplikaci.</string>
<string name="error_pc_offline">Počítač je offline</string>
<string name="unpair_fail">Zrušení párování se nezdařilo</string>
<string name="error_404">GFE vrátilo HTTP chybu 404. Ujistěte se, že vaše PC má podporované GPU. Tato chyba může být způsobena i použitím softwaru pro vzdálenou plochu. Zkuste restartovat počítač, nebo přeinstalujte GFE.</string>
<string name="title_decoding_error">Dekodér videa spadnul</string>
<string name="error_usb_prohibited">Správce zařízení neumožňuje přístup k USB. Zkontrolujte nastavení Knoxu nebo MDM.</string>
<string name="message_decoding_error">Moonlight spadnul kvůli nekompatibilnímu video dekodéru na tomto zařízení. Ujistěte se, že je GeForce Experience na vašem PC aktualizováno na nejnovější verzi. Zkuste upravit nastavení streamování, pokud aplikace padá opakovaně.</string>
<string name="message_decoding_reset">Video dekodér vašeho zařízení při současných nastaveních streamování padá. Vaše nastavení streamování byla resetována na výchozí.</string>
<string name="video_decoder_init_failed">Nezdařilo se spustit video dekodér. Vaše zařízení nemusí podporovat zvolené rozlišení nebo snímkovou frekvenci.</string>
<string name="no_video_received_error">Od hostitele nebylo přijato žádné video.</string>
<string name="no_frame_received_error">Vaše připojení k síti není dost rychlé. Zkuste snížit datový tok videa nebo použijte rychlejší připojení.</string>
<string name="applist_menu_hide_app">Skrýt aplikaci</string>
<string name="title_add_pc">Přidat PC ručně</string>
<string name="title_audio_config_list">Konfigurace prostorového zvuku</string>
<string name="searching_pc">Hledání PC, na kterých běží GameStream...
\n
\nUjistěte se, že je GameStream povolen v záložce SHIELD v nastavení GeForce Experience.</string>
<string name="applist_menu_quit">Ukončit</string>
<string name="applist_menu_quit_and_start">Ukončit současnou hru a spustit</string>
<string name="applist_menu_cancel">Zrušit</string>
<string name="applist_menu_tv_channel">Přidat do kanálu</string>
<string name="applist_refresh_title">Seznam aplikací</string>
<string name="applist_menu_resume">Pokračovat</string>
<string name="applist_menu_details">Zobrazit detaily</string>
<string name="applist_menu_scut">Vytvořit zkratku</string>
<string name="addpc_success">Počítač přidán úspěšně</string>
<string name="applist_details_id">ID aplikace:</string>
<string name="addpc_fail">K zadanému počítači se nepodařilo připojit. Ujistěte se, že jsou ve firewallu povoleny nezbytné porty.</string>
<string name="addpc_enter_ip">Musíte zadat IP adresu</string>
<string name="title_native_res_dialog">Varování pro nativní rozlišení</string>
<string name="title_checkbox_vibrate_fallback">Emulovat podporu vibrací</string>
<string name="title_seekbar_deadzone">Upravit deadzone analogových páček</string>
<string name="check_ports_msg">Zkontrolujte svůj firewall a pravidla přesměrování pro tyto porty:</string>
<string name="conn_terminated_msg">Spojení bylo ukončeno</string>
<string name="ip_hint">IP adresa GeForce PC</string>
<string name="conn_hardware_latency">Průměrné zpoždění hardwarového dekodéru:</string>
<string name="conn_client_latency">Průměrné zpoždění při dekódování snímků:</string>
<string name="perf_overlay_netlatency">Průměrné zpoždění sítě: %1$d ms (odchylka: %2$d ms)</string>
<string name="perf_overlay_dectime">Průměrný čas pro dekódování: %1$.2f ms</string>
<string name="applist_connect_msg">Připojování k PC…</string>
<string name="title_checkbox_touchscreen_trackpad">Použít dotykový displej jako trackpad</string>
<string name="title_checkbox_multi_controller">Automatická detekce připojení herního ovladače</string>
<string name="summary_checkbox_multi_controller">Odškrtnutí této možnosti vynutí, aby byl herní ovladač vždy připojen</string>
<string name="summary_checkbox_xb1_driver">Povolí zabudovaný USB ovladač pro zařízení bez nativní podpory pro Xbox ovladač</string>
<string name="summary_checkbox_vibrate_fallback">Rozvibruje vaše zařízení pro emulaci vibrací ovladače, pokud je váš herní ovladač nepodporuje</string>
<string name="suffix_seekbar_deadzone">%</string>
<string name="summary_seekbar_deadzone">Poznámka: Některé hry mohou vynutit větší deadzone, než jaká je nastavena v Moonlightu.</string>
<string name="title_checkbox_xb1_driver">Xbox 360/One USB gamepad ovladač</string>
<string name="title_checkbox_usb_bind_all">Vynutit nativní podporu herního ovladače Xbox</string>
<string name="summary_checkbox_mouse_emulation">Dlouhým podržením tlačítka Start přepnete herní ovladač do režimu myši</string>
<string name="summary_checkbox_usb_bind_all">Použít USB ovladač Moonlightu pro všechny podporované gamepady, i když existuje nativní podpora pro Xbox ovladač</string>
<string name="title_checkbox_mouse_emulation">Emulace myši pomocí herního ovladače</string>
<string name="title_checkbox_flip_face_buttons">Přehodit tlačítka A/B, X/Y</string>
<string name="title_checkbox_absolute_mouse_mode">Režim myši pro vzdálenou plochu</string>
<string name="summary_checkbox_absolute_mouse_mode">Tímto zapnete přirozenější zrychlování myši pro použití ve vzdálené ploše, ale možnost je nekompatibilní se spoustou her.</string>
<string name="summary_osc_opacity">Zmenšete či zvětšete průhlednost ovladače na obrazovce</string>
<string name="summary_only_l3r3">Skryje veškerá virtuální tlačítka kromě L3 a R3</string>
<string name="category_ui_settings">Nastavení zobrazení</string>
<string name="suffix_osc_opacity">%</string>
<string name="title_setup_guide">Průvodce nastavením</string>
<string name="title_checkbox_disable_warnings">Zakázat varovací zprávy</string>
<string name="category_help">Nápověda</string>
<string name="summary_checkbox_disable_warnings">Zakáže varování o pomalém připojení během streamování</string>
<string name="title_disable_frame_drop">Nezahazovat snímky</string>
<string name="title_enable_perf_overlay">Zobrazit během streamování informace o výkonu</string>
<string name="summary_enable_perf_overlay">Zobrazit realtime informace o výkonu streamu během streamování</string>
<string name="resolution_4k">4K</string>
<string name="fps_30">30 FPS</string>
<string name="title_troubleshooting">Průvodce řešením problémů</string>
<string name="summary_troubleshooting">Zobrazit tipy pro diagnózu a opravu běžných problémů se streamováním</string>
<string name="resolution_720p">720p</string>
<string name="resolution_1080p">1080p</string>
<string name="resolution_1440p">1440p</string>
<string name="videoformat_hevcauto">Automaticky</string>
<string name="audioconf_71surround">7.1 prostorový zvuk</string>
<string name="pacing_balanced">Vyvážené</string>
<string name="pacing_smoothness">Preferovat plynulejší video (může výrazně zvýšit zpoždění)</string>
<string name="resolution_prefix_native_landscape">(na šířku)</string>
<string name="resolution_prefix_native_portrait">(na výšku)</string>
<string name="category_audio_settings">Nastavení zvuku</string>
<string name="title_checkbox_enable_audiofx">Povolit podporu systémového ekvalizéru</string>
<string name="category_input_settings">Nastavení vstupu</string>
<string name="summary_setup_guide">Zobrazit instrukce k nastavení vašeho herního PC pro streamování</string>
<string name="dialog_title_osc_opacity">Změnit průhlednost</string>
<string name="fps_60">60 FPS</string>
<string name="fps_90">90 FPS</string>
<string name="fps_120">120 FPS</string>
<string name="audioconf_stereo">Stereo</string>
<string name="audioconf_51surround">5.1 prostorový zvuk</string>
<string name="help_loading_msg">Načítání stránky s nápovědou…</string>
<string name="pcview_menu_header_online">Online</string>
<string name="pcview_menu_header_offline">Offline</string>
<string name="pcview_menu_header_unknown">Obnovování</string>
<string name="pcview_menu_app_list">Zobrazit všechny aplikace</string>
<string name="pcview_menu_pair_pc">Spárovat s PC</string>
<string name="pcview_menu_unpair_pc">Zrušit párování</string>
<string name="pcview_menu_send_wol">Poslat Wake-On-LAN požadavek</string>
<string name="pcview_menu_delete_pc">Smazat PC</string>
<string name="pcview_menu_test_network">Otestovat připojení k síti</string>
<string name="pcview_menu_details">Zobrazit detaily</string>
<string name="nettest_title_done">Test sítě dokončen</string>
<string name="nettest_text_inconclusive">Test sítě nemohl být proveden, protože se nezdařilo připoojení k žádným z testovacíh serverů Moonlight. Zkontrolujte své připojení k Internetu, nebo to zkuste znovu později.</string>
<string name="nettest_text_failure">Současná síť vašeho počítače nejspíš blokuje Moonlight. Streamování přes Internet nemusí během připojení k této síti fungovat.
\n
\nNásledující porty byly zablokovány:
\n</string>
<string name="nettest_text_blocked">Vaše současné připojení k síti blokuje Moonlight. Streamování přes Internet nemusí fungovat, dokud jste připojeni k této síti.</string>
<string name="pair_pc_ingame">Na počítači momentálně běží hra. Před párováním musíte hru zavřít.</string>
<string name="pair_pairing_title">Párování</string>
<string name="pair_pairing_msg">Vložte prosím následující PIN na cílovém PC:</string>
<string name="pair_incorrect_pin">Nesprávný PIN</string>
<string name="pair_fail">Párování selhalo</string>
<string name="pair_already_in_progress">Párování již probíhá</string>
<string name="wol_pc_online">Počítač je online</string>
<string name="wol_no_mac">Nezdařilo se probudit PC, protože GFE nezaslalo MAC adresu</string>
<string name="title_decoding_reset">Reset nastavení videa</string>
<string name="unable_to_pin_shortcut">Váš současný launcher neumožňuje vytváření zástupců.</string>
<string name="conn_establishing_msg">Připojování</string>
<string name="conn_starting">Spouštění</string>
<string name="conn_error_title">Chyba připojení</string>
<string name="frame_conversion_error">Hostitelský počítač hlásí fatální chybu enkódování videa.
\n
\nZkuste vypnout HDR, změňte rozlišení streamu nebo rozlišení displeje hostitelského PC.</string>
<string name="yes">Ano</string>
<string name="no">Ne</string>
<string name="lost_connection">Připojení k PC bylo ztraceno</string>
<string name="title_details">Detaily</string>
<string name="perf_overlay_renderingfps">Vykreslovací snímková frekvence: %1$.2f FPS</string>
<string name="perf_overlay_netdrops">Snímky zahozeny vašim připojením: %1$.2f%%</string>
<string name="applist_refresh_msg">Obnovování aplikací…</string>
<string name="applist_refresh_error_title">Chyba</string>
<string name="applist_refresh_error_msg">Nezdařilo se získat seznam aplikací</string>
<string name="applist_quit_app">Ukončování</string>
<string name="applist_quit_success">Úspěšně ukončeno</string>
<string name="applist_quit_fail">Ukončení se nezdařilo</string>
<string name="applist_quit_confirmation">Určitě chcete ukončit běžící aplikaci\? Neuložená data budou ztracena.</string>
<string name="msg_add_pc">Připojování k PC…</string>
<string name="addpc_unknown_host">Nezdařilo se připojit k adrese PC. Ujistěte se, že v adrese není překlep.</string>
<string name="addpc_wrong_sitelocal">Tahle adresa nevypadá správně. Musíte zadat veřejnou IP vašeho routeru, pokud chcete streamovat přes Internet.</string>
<string name="category_basic_settings">Základní nastavení</string>
<string name="title_resolution_list">Rozlišení videa</string>
<string name="summary_resolution_list">Zvyšte přo zlepšení ostrosti obrazu. Snižte pro lepší výkon na levnějších zařízeních nebo pomalejších sítích.</string>
<string name="summary_audio_config_list">Povolit 5.1 nebo 7.1 prostorový zvuk pro systémy domácího kina</string>
<string name="summary_checkbox_touchscreen_trackpad">Pokud je povoleno, dotykový displej funguje jako trackpad. Pokud je zakázáno, dotykový displej ovládá kurzor myši přímo.</string>
<string name="title_reset_osc">Vymazat uložené rozložení ovladače na obrazovce</string>
<string name="summary_reset_osc">Resetuje všechna nastavení ovladače na obrazovce na jejich výchozí velikost a pozici</string>
<string name="title_osc_opacity">Změnit průhlednost ovladače na obrazovce</string>
<string name="category_advanced_settings">Pokročilá nastavení</string>
<string name="title_unlock_fps">Odemknout všechny možné snímkové frekvence</string>
<string name="title_checkbox_reduce_refresh_rate">Povolit snížení obnovovací frekvence</string>
<string name="summary_checkbox_reduce_refresh_rate">Menší obnovovací frekvence displeje může šetřit energii výměnou za zvýšení zpoždění videa</string>
<string name="title_checkbox_mouse_nav_buttons">Povolit tlačítka myši zpět a vpřed</string>
<string name="summary_checkbox_mouse_nav_buttons">Povolení této možnosti může na některých pochybných zařízeních rozbít klikání pravým tlačítkem</string>
<string name="summary_checkbox_flip_face_buttons">Přehodí tlačítka A/B a X/Y na herním ovladači a instrukcích na obrazovce</string>
<string name="toast_reset_osc_success">Ovladač na obrazovce resetován</string>
<string name="dialog_title_reset_osc">Reset rozložení</string>
<string name="dialog_text_reset_osc">Jste si jisti, že chcete smazat vaše uložené rozložení ovladače\?</string>
<string name="title_checkbox_enable_pip">Povolit sledovací rezim obraz-v-obraze</string>
<string name="summary_checkbox_enable_sops">Povolit GFE měnit herní nastavení pro optimální streamování</string>
<string name="title_checkbox_host_audio">Přehrávat zvuk na PC</string>
<string name="summary_checkbox_host_audio">Přehraje zvuk z počítače a tohoto zařízení</string>
<string name="summary_unlock_fps">Streamování v 90 nebo 120 FPS může snížit zpoždění na dražších zařízeních, ale může způsobit zasekávání nebo nestabilitu na zařízeních, které je nepodporují</string>
<string name="title_enable_post_stream_toast">Zobrazit informace o zpoždění po streamování</string>
<string name="summary_enable_post_stream_toast">Zobrazit informace o zpoždění po skončení streamování</string>
<string name="title_privacy_policy">Zásady ochrany osobních údajů</string>
<string name="summary_privacy_policy">Zobrazit zásady ochrany osobních údajů Moonlightu</string>
<string name="resolution_360p">360p</string>
<string name="resolution_480p">480p</string>
<string name="pacing_balanced_alt">Vyvážené s limitem FPS</string>
<string name="scut_deleted_pc">PC smazán</string>
<string name="scut_not_paired">PC nespárován</string>
<string name="scut_pc_not_found">PC nenalezen</string>
<string name="scut_invalid_uuid">Zadaný počítač není platný</string>
<string name="scut_invalid_app_id">Zadaná aplikace není platná</string>
<string name="help_loading_title">Zobrazení nápovědy</string>
<string name="wol_waking_msg">Může trvat pár sekund, než se váš počítač probudí. Pokud se tak nestane, ujistěte se, že máte správně nastaveno Wake-On-LAN.</string>
<string name="wol_fail">Nezdařilo se odeslat Wake-On-LAN pakety</string>
<string name="help">Nápověda</string>
<string name="delete_pc_msg">Určitě chcete smazat tento PC\?</string>
<string name="slow_connection_msg">Pomalé připojení k PC
\nSnižte datový tok</string>
<string name="poor_connection_msg">Špatné připojení k PC</string>
<string name="perf_overlay_streamdetails">Video stream: %1$s %2$.2f FPS</string>
<string name="perf_overlay_decoder">Dekodér: %1$s</string>
<string name="perf_overlay_incomingfps">Příchozí snímková frekvence po síti: %1$.2f FPS</string>
<string name="text_native_res_dialog">GeForce Experience oficiálně nepodporuje nativní rozlišení a proto nenastaví rozlišení displeje vašeho hostitelského PC. Musíte jej nastavit ručně ve hře.
\n
\nPokud v NVIDIA Control Panelu vytvoříte vlastní rozlišení pro vaše zařízení, prosím ujistěte se, že jste si přečetli a že chápete varování od NVIDIE ohledně možného poškození monitoru, nestability PC a dalších možných problémů.
\n
\nNejsme zodpovědni za žádné problémy, které vzniknou používáním vlastního rozlišení na vašem PC.
\n
\nA nakonec, vaše zařízení nebo hostitelský počítač nemusí podporovat streamování v nativním rozlišení. Pokud vám to nefunguje, bohužel se s tím nedá nic dělat.</string>
<string name="title_fps_list">Snímková frekvence videa</string>
<string name="summary_fps_list">Zvyšte pro plynulejší video stream. Snižte pro lepší výkon na levnějších zařízeních.</string>
<string name="title_seekbar_bitrate">Datový tok videa</string>
<string name="summary_seekbar_bitrate">Zvyšte pro lepší kvalitu obrazu. Snižte pro zlepšení výkonu u pomalých připojení.</string>
<string name="suffix_seekbar_bitrate_mbps">Mbps</string>
<string name="title_checkbox_stretch_video">Natáhnout video na celou obrazovku</string>
<string name="resolution_prefix_native">Nativní</string>
<string name="category_on_screen_controls_settings">Nastavení ovládání na obrazovce</string>
<string name="title_checkbox_show_onscreen_controls">Zobrazovat ovládání na obrazovce</string>
<string name="summary_checkbox_show_onscreen_controls">Zobrazit překrytí virtuálního ovladače na dotykovém displeji</string>
<string name="title_checkbox_vibrate_osc">Povolit vibrace</string>
<string name="summary_checkbox_vibrate_osc">Vibruje vašim zařízením pro emulaci vibrací ovladače při použití ovladače na obrazovce</string>
<string name="title_only_l3r3">Zobrazit pouze L3 a R3</string>
<string name="summary_checkbox_enable_pip">Umožní, aby byl stream sledován (ale ne ovládá) během multitaskingu</string>
<string name="title_language_list">Jazyk</string>
<string name="summary_language_list">Jazyk, který bude Moonlight používat</string>
<string name="title_checkbox_small_icon_mode">Použít malý box art</string>
<string name="summary_checkbox_small_icon_mode">Díky menšímu box artu v seznamu aplikací uvidíte na obrazovce více aplikací naráz</string>
<string name="category_host_settings">Nastavení hostitele</string>
<string name="title_checkbox_enable_sops">Optimalizovat herní nastavení</string>
<string name="summary_disable_frame_drop">Může na některých zařízeních snížit mikrozádrhy, ale může zvýšit zpoždění</string>
<string name="title_video_format">Změnit nastavení HEVC</string>
<string name="summary_video_format">HEVC sníží datový přenos, ale vyžaduje novější zařízení</string>
<string name="title_enable_hdr">Povolit HDR (experimentální)</string>
<string name="summary_enable_hdr">Streamovat v HDR, pokud jej hra a GPU počítače podporují. HDR vyžaduje GPU GTX 1000 nebo novější.</string>
<string name="videoformat_hevcalways">Vždy použít HEVC (může padat)</string>
<string name="videoformat_hevcnever">Nikdy nepoužívat HEVC</string>
<string name="title_frame_pacing">Frame pacing videa</string>
<string name="summary_frame_pacing">Zvolte, jak vyvážit zpoždění videa a jeho plynulost</string>
<string name="pacing_latency">Preferovat nejnižší zpoždění</string>
</resources>
<resources></resources>
+4 -13
View File
@@ -76,7 +76,7 @@
<string name="addpc_enter_ip">Debes introducir una dirección IP</string>
<!-- Preferences -->
<string name="category_basic_settings">Configuración básica</string>
<string name="title_resolution_list">Seleccionar resolución</string>
<string name="title_resolution_list">Seleccionar resolución y FPS</string>
<string name="summary_resolution_list">Establecer unos valores demasiado altos puede causar retraso o cierres inesperados.</string>
<string name="title_seekbar_bitrate">Seleccionar bitrate de vídeo</string>
<string name="summary_seekbar_bitrate">Usa bitrate bajo para reducir "parpadeo". Incrementa el bitrate para mayor calidad de imagen.</string>
@@ -109,8 +109,8 @@
<string name="title_video_format">Cambiar configuración HEVC</string>
<string name="summary_video_format">HEVC reduce el ancho de banda de vídeo, pero requiere un dispositivo reciente</string>
<!-- Array strings -->
<string name="videoformat_hevcauto">Automático (Recomendado)</string>
<string name="videoformat_hevcalways">Preferir HEVC</string>
<string name="videoformat_hevcauto">Usar HEVC sólo si es estable</string>
<string name="videoformat_hevcalways">Siempre usar HEVC (puede fallar)</string>
<string name="videoformat_hevcnever">Nunca usar HEVC</string>
<string name="nettest_title_done">Prueba de Red Completada</string>
<string name="scut_not_paired">PC no emparejado</string>
@@ -165,7 +165,7 @@
<string name="resolution_1440p">1440p</string>
<string name="resolution_4k">4K</string>
<string name="suffix_osc_opacity">%</string>
<string name="title_checkbox_enable_pip">Activar modo Pantalla-en-Pantalla para modo espectador</string>
<string name="title_checkbox_enable_pip">Actividad modo Pantalla-en-Pantalla para observador</string>
<string name="resolution_720p">720p</string>
<string name="fps_120">120 FPS</string>
<string name="audioconf_71surround">7.1 Sonido Envolvente</string>
@@ -256,13 +256,4 @@
<string name="fps_60">60 FPS</string>
<string name="fps_90">90 FPS</string>
<string name="title_frame_pacing">Ritmo de cuadros por segundo en video</string>
<string name="resolution_prefix_native_portrait">(Retrato)</string>
<string name="frame_conversion_error">El PC anfitrión ha reportado un error fatal en el codificador de video.
\n
\nIntenta deshabilitar el modo HDR, cambiar la resolución de la transmisión, o cambiar la resolución de pantalla del PC anfitrión.</string>
<string name="resolution_prefix_native_landscape">(Panorama)</string>
<string name="summary_checkbox_reduce_refresh_rate">Tasa de refresco menores pueden ahorrar energía a cambio de una mayor latencia de video</string>
<string name="title_checkbox_reduce_refresh_rate">Permitir reducción de la tasa de refresco</string>
<string name="title_full_range">Usar rango (0-255) de color completo</string>
<string name="summary_full_range">Esto puede causar problemas de video o bloqueos si la pantalla de tu dispositivo no puede manejar contenido de rango completo.</string>
</resources>
+2 -7
View File
@@ -228,8 +228,8 @@
<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">Automatique (recommandé)</string>
<string name="videoformat_hevcalways">Préférez le HEVC</string>
<string name="videoformat_hevcauto">Automatique</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>
@@ -259,9 +259,4 @@
<string name="summary_checkbox_reduce_refresh_rate">Des taux de rafraîchissement d\'affichage plus bas peuvent économiser de l\'énergie au détriment d\'une latence vidéo plus importante</string>
<string name="summary_checkbox_enable_audiofx">Permet aux effets audio de fonctionner lors du streaming, mais peut augmenter la latence</string>
<string name="title_checkbox_enable_audiofx">Activer le support de l\'égalisateur système</string>
<string name="frame_conversion_error">Le PC hôte a signalé une erreur d\'encodage fatale.
\n
\nEssayez de désactiver le mode HDR, de changer la résolution du flux ou la résolution de votre PC hôte.</string>
<string name="title_full_range">Forcer la vidéo sur toute la gamme de couleurs (expérimental)</string>
<string name="summary_full_range">Ceci entraînera une perte de détails dans les zones claires et sombres si votre appareil n\'affiche pas correctement le contenu vidéo de la gamme complète de couleurs.</string>
</resources>
-9
View File
@@ -254,13 +254,4 @@
<string name="title_privacy_policy">Informativa sulla privacy</string>
<string name="summary_troubleshooting">Visualizza i suggerimenti per la diagnosi e la risoluzione dei problemi di streaming più comuni</string>
<string name="summary_privacy_policy">Visualizza l\'informativa sulla privacy di Moonlight</string>
<string name="frame_conversion_error">Il PC host ha segnalato un errore fatale di codifica video.
\n
\nProva a disabilitare la modalità HDR, modificare la risoluzione dello streaming o la risoluzione del display del tuo PC host.</string>
<string name="summary_checkbox_reduce_refresh_rate">Una minore frequenza di aggiornamento del display può risparmiare energia a scapito di una latenza video aggiuntiva</string>
<string name="resolution_prefix_native_landscape">(Panorama)</string>
<string name="resolution_prefix_native_portrait">(Ritratto)</string>
<string name="title_checkbox_enable_audiofx">Abilita il supporto per l\'equalizzatore di sistema</string>
<string name="summary_checkbox_enable_audiofx">Consente agli effetti audio di funzionare durante lo streaming, ma può aumentare la latenza audio</string>
<string name="title_checkbox_reduce_refresh_rate">Consenti riduzione della frequenza di aggiornamento</string>
</resources>
+2 -7
View File
@@ -53,8 +53,8 @@
<string name="resolution_4k">4K</string>
<string name="fps_30">30 FPS</string>
<string name="fps_60">60 FPS</string>
<string name="videoformat_hevcalways">Prefira HEVC</string>
<string name="videoformat_hevcauto">Automático (recomendado)</string>
<string name="videoformat_hevcalways">Sempre usar HEVC (talvez crashe)</string>
<string name="videoformat_hevcauto">Automático</string>
<string name="fps_120">120 FPS</string>
<string name="audioconf_stereo">Stereo</string>
<string name="audioconf_51surround">5.1 Surround</string>
@@ -245,9 +245,4 @@
<string name="resolution_prefix_native_portrait">(Retrato)</string>
<string name="title_checkbox_enable_audiofx">Habilitar sistema de suporte à equalização</string>
<string name="summary_checkbox_enable_audiofx">Permitir que efeitos de audio funcionem durante o streaming, pode acrescentar latência de audio</string>
<string name="title_full_range">Forçar vídeo de gama completa de cores (Experimental)</string>
<string name="frame_conversion_error">O PC host relatou um erro fatal de codificação de vídeo.
\n
\nTente desativar o modo HDR, alterar a resolução de streaming ou alterar a resolução do PC host.</string>
<string name="summary_full_range">Isso causará perda de detalhes em áreas claras e escuras se o seu dispositivo não exibir corretamente todo o conteúdo de vídeo em cores.</string>
</resources>
+2 -24
View File
@@ -218,8 +218,8 @@
<string name="pcview_menu_header_offline">Поза мережею</string>
<string name="pcview_menu_header_online">В мережі</string>
<!-- Array strings -->
<string name="videoformat_hevcauto">Автоматичний (рекомендовано)</string>
<string name="videoformat_hevcalways">Використовувати HEVC</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="summary_frame_pacing">Укажіть баланс відео затримки та плавності</string>
@@ -239,26 +239,4 @@
<string name="audioconf_stereo">Стерео</string>
<string name="audioconf_51surround">5.1 Об\'ємний Звук</string>
<string name="audioconf_71surround">7.1 Об\'ємний Звук</string>
<string name="summary_checkbox_enable_audiofx">Дозволяє аудіоефектам функціонувати під час потокового передавання, але може збільшити затримку звуку</string>
<string name="title_troubleshooting">Гайд з усунення несправностей</string>
<string name="title_privacy_policy">Політика конфіденційності</string>
<string name="summary_troubleshooting">Переглянути поради щодо діагностики та усунення поширених проблем з потоковою передачею</string>
<string name="summary_checkbox_reduce_refresh_rate">Більш низька частота оновлення дисплея може заощадити енергію за рахунок деякої додаткової затримки відео</string>
<string name="summary_seekbar_deadzone">Примітка: Деякі ігри можуть встановлювати більшу мертву зону, ніж та, на яку налаштовано Moonlight.</string>
<string name="title_checkbox_absolute_mouse_mode">Режим миші віддаленого робочого столу</string>
<string name="title_setup_guide">Гайд по налаштуванню</string>
<string name="summary_setup_guide">Переглянути інструкцію, як налаштувати ігровий ПК для стрімінгу</string>
<string name="pacing_balanced_alt">Збалансований з лімітом FPS</string>
<string name="resolution_prefix_native_landscape">(Горизонтальний)</string>
<string name="resolution_prefix_native_portrait">(Портретний)</string>
<string name="title_checkbox_enable_audiofx">Увімкнення підтримки системного еквалайзера</string>
<string name="summary_checkbox_absolute_mouse_mode">Це може зробити прискорення миші більш природним під час використання віддаленого робочого столу, але воно несумісне з багатьма іграми.</string>
<string name="title_checkbox_reduce_refresh_rate">Дозволити зниження частоти оновлення</string>
<string name="category_help">Допомога</string>
<string name="summary_privacy_policy">Переглянути політику конфіденційності Moonlight</string>
<string name="frame_conversion_error">Головний комп\'ютер повідомив про фатальну помилку кодування відео.
\n
\nСпробуйте вимкнути режим HDR, змінити роздільну здатність потокового відео або змінити роздільну здатність дисплея головного комп\'ютера.</string>
<string name="title_full_range">Сила повного спектру відео (експериментальна)</string>
<string name="summary_full_range">Це може призвести до втрати деталей у світлих і темних областях, якщо пристрій не відображає належним чином весь діапазон відеоконтенту.</string>
</resources>
+2 -2
View File
@@ -222,8 +222,8 @@
<string name="audioconf_stereo">立体声</string>
<string name="audioconf_51surround">5.1环绕声</string>
<string name="audioconf_71surround">7.1环绕声</string>
<string name="videoformat_hevcauto">自动(推荐)</string>
<string name="videoformat_hevcalways">首选 HEVC</string>
<string name="videoformat_hevcauto">自动</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>
+8 -10
View File
@@ -56,7 +56,7 @@
<string name="conn_hardware_latency">硬體解碼器平均延時:</string>
<string name="conn_starting">正在啟動</string>
<string name="conn_error_title">連線錯誤</string>
<string name="conn_error_msg">無法啟動</string>
<string name="conn_error_msg"> 啟動失敗 </string>
<string name="conn_terminated_title">連線已終止</string>
<string name="conn_terminated_msg">連線已終止</string>
<!-- General strings -->
@@ -90,10 +90,10 @@
<string name="applist_refresh_title">遊戲清單</string>
<string name="applist_refresh_msg">正在重新整理…</string>
<string name="applist_refresh_error_title"> 錯誤 </string>
<string name="applist_refresh_error_msg">無法取得遊戲清單</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_fail">結束失敗</string>
<string name="applist_quit_confirmation">您確定要結束執行中的遊戲?所有未儲存的資料將丟失。</string>
<string name="applist_details_id">App ID:</string>
<!-- Add computer manually activity -->
@@ -109,9 +109,9 @@
<string name="title_resolution_list">視訊解析度</string>
<string name="summary_resolution_list">高解析度提升圖像清晰度。低解析度提升在低效能裝置和較慢網路中的串流體驗。</string>
<string name="title_fps_list">視訊影格速率</string>
<string name="summary_fps_list">提高影格速率以取得更順暢的視訊串流,降低可在低效能裝置上取得更好的串流體驗。</string>
<string name="summary_fps_list">提高影格速率以獲得更順暢的視訊串流,降低可在低效能裝置上獲得更好的串流體驗。</string>
<string name="title_seekbar_bitrate">視訊位元速率</string>
<string name="summary_seekbar_bitrate">提高位元速率以提升圖像品質,降低可在較慢的網路中取得更好的串流體驗。</string>
<string name="summary_seekbar_bitrate">提高位元速率以提升圖像品質,降低可在較慢的網路中獲得更好的串流體驗。</string>
<string name="title_unlock_fps">解鎖所有可用影格速率</string>
<string name="summary_unlock_fps">以 90 或 120 畫面更新率串流可能會減少在高效能裝置上的網路延時,但會在不支援的裝置上造成卡頓或崩潰</string>
<string name="title_checkbox_stretch_video">將畫面延展至全螢幕</string>
@@ -197,7 +197,7 @@
\n如果問題仍然存在,請嘗試重新安裝 GPU 驅動程式和 GFE。</string>
<string name="no_frame_received_error">您的網路連線品質不佳。降低視訊位元速率設定或更換更快的連線。</string>
<string name="no_video_received_error">沒有接收到來自主機的視訊。</string>
<string name="video_decoder_init_failed">無法初始化視訊解碼器,您的裝置可能不支援選取的解析度或影格速率。</string>
<string name="video_decoder_init_failed">視訊解碼器初始化失敗。您的裝置可能不支援選取的解析度或影格速率。</string>
<string name="nettest_text_blocked">您裝置目前的網路連線封鎖了 Moonlight。連線到該網路時可能無法透過網際網路串流。</string>
<string name="nettest_text_failure">您裝置目前的網路連線似乎封鎖了 Moonlight。連線到該網路時可能無法透過網際網路串流。
\n
@@ -223,8 +223,8 @@
<string name="audioconf_stereo">立體聲</string>
<string name="audioconf_51surround">5.1 環場音效</string>
<string name="audioconf_71surround">7.1 環場音效</string>
<string name="videoformat_hevcauto">自動 (建議)</string>
<string name="videoformat_hevcalways">優先使用 HEVC</string>
<string name="videoformat_hevcauto">自動</string>
<string name="videoformat_hevcalways">強制使用 HEVC (可能會當機)</string>
<string name="videoformat_hevcnever">不使用 HEVC</string>
<string name="resolution_4k">4K</string>
<string name="fps_30">30 FPS</string>
@@ -261,6 +261,4 @@
<string name="frame_conversion_error">主機電腦回報了一個嚴重的視訊編碼錯誤。
\n
\n嘗試停用 HDR 模式,變更串流解析度,或變更您的主機電腦的顯示器解析度。</string>
<string name="title_full_range">強制全範圍視訊 (實驗性)</string>
<string name="summary_full_range">若您的裝置無法正確地顯示全範圍視訊內容,將會導致淺色區域和深色區域的細節遺失。</string>
</resources>
+6 -9
View File
@@ -9,14 +9,13 @@
<item>@string/resolution_4k</item>
</string-array>
<!-- Keep this in sync with PreferenceConfiguration.isNativeResolution()! -->
<string-array name="resolution_values" translatable="false">
<item>640x360</item>
<item>854x480</item>
<item>1280x720</item>
<item>1920x1080</item>
<item>2560x1440</item>
<item>3840x2160</item>
<item>s_640x360</item>
<item>s_854x480</item>
<item>s_1280x720</item>
<item>s_1920x1080</item>
<item>s_2560x1440</item>
<item>s_3840x2160</item>
</string-array>
<string-array name="fps_names">
@@ -64,7 +63,6 @@
<item>Magyar</item>
<item>Ελληνικά</item>
<item>Português do Brasil</item>
<item>Čeština</item>
</string-array>
<string-array name="language_values" translatable="false">
<item>default</item>
@@ -86,7 +84,6 @@
<item>hu</item>
<item>el</item>
<item>pt-BR</item>
<item>cs</item>
</string-array>
<string-array name="video_format_names">
+2 -4
View File
@@ -229,8 +229,6 @@
<string name="summary_video_format">HEVC lowers video bandwidth requirements but requires a newer device</string>
<string name="title_enable_hdr">Enable HDR (Experimental)</string>
<string name="summary_enable_hdr">Stream HDR when the game and PC GPU support it. HDR requires a GTX 1000 series GPU or later.</string>
<string name="title_full_range">Force full range video (Experimental)</string>
<string name="summary_full_range">This will cause loss of detail in light and dark areas if your device doesn\'t properly display full range video content.</string>
<string name="title_enable_perf_overlay">Show performance stats while streaming</string>
<string name="summary_enable_perf_overlay">Display real-time stream performance information while streaming</string>
<string name="title_enable_post_stream_toast">Show latency message after streaming</string>
@@ -261,8 +259,8 @@
<string name="audioconf_51surround">5.1 Surround Sound</string>
<string name="audioconf_71surround">7.1 Surround Sound</string>
<string name="videoformat_hevcauto">Automatic (Recommended)</string>
<string name="videoformat_hevcalways">Prefer HEVC</string>
<string name="videoformat_hevcauto">Automatic</string>
<string name="videoformat_hevcalways">Always use HEVC (may crash)</string>
<string name="videoformat_hevcnever">Never use HEVC</string>
<string name="title_frame_pacing">Video frame pacing</string>
-1
View File
@@ -19,5 +19,4 @@
<locale android:name="hu"/>
<locale android:name="el"/>
<locale android:name="pt-BR"/>
<locale android:name="cs"/>
</locale-config>
-5
View File
@@ -211,11 +211,6 @@
android:title="@string/title_enable_hdr"
android:summary="@string/summary_enable_hdr"
android:defaultValue="false" />
<CheckBoxPreference
android:key="checkbox_full_range"
android:title="@string/title_full_range"
android:summary="@string/summary_full_range"
android:defaultValue="false" />
<CheckBoxPreference
android:key="checkbox_enable_perf_overlay"
android:title="@string/title_enable_perf_overlay"
@@ -1,7 +0,0 @@
- Changed the default SDR colorspace from BT.601 to BT.709
- Changed the input capture toggle shortcut from Ctrl+Shift+Z to Ctrl+Alt+Shift+Z for consistency with other clients
- Toggling input capture now properly toggles keyboard capture on Samsung devices
- PC state is now refreshed more quickly after a network change
- Fixed entering IPv6 addresses on the Add PC page
- Added an experimental option to request full range video
- Updated community contributed translations from Weblate