RedTubeCom:

-added quality settings
-fixes thread 87685

git-svn-id: svn://svn.jdownloader.org/jdownloader/trunk@44481 ebf7c1c2-ba36-0410-9fe8-c592906822b4

Former-commit-id: 0335c65d3d2f30ff3479bdc13d6b7516b7d9bc41
This commit is contained in:
jiaz 2021-06-16 08:36:27 +00:00
parent 478bf3a2e5
commit ed4db5f338
4 changed files with 261 additions and 120 deletions

View File

@ -1,84 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="jd/plugins/optional/neembuu/|jd/plugins/optional/remoteserv/|jd/plugins/optional/remoteserv/|org/jdownloader/extensions/langfileeditor/" kind="src" path="src"/>
<classpathentry kind="src" path="src-closed"/>
<classpathentry kind="src" path="translations"/>
<classpathentry kind="src" path="themes"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="jd/ressourcen/libs/dbus"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/irclib.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/synthetica.jar" sourcepath="C:/Users/Thomas/Downloads/synthetica.src.2.zip">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/jd/ressourcen/code-ressourcen/synthetica_docs.zip!/"/>
<attribute name="source_encoding" value="UTF-8"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlackMoon.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlackStar.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlueIce.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlueMoon.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlueSteel.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaMauveMetallic.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaOrangeMetallic.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaSilverMoon.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaSimple2D.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaSkyMetallic.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaWhiteVision.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jna.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlackEye.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaGreenDream.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/dbus/debug-disable.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/dbus/hexdump.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/dbus/libdbus-java.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/dbus/unix.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbinding.jar"/>
<classpathentry kind="lib" path="ressourcen/libs_ext/AppleJavaExtensions.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/JDBrowser"/>
<classpathentry combineaccessrules="false" kind="src" path="/AppWorkUtils"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbindingWin.jar"/>
<classpathentry kind="lib" path="/AppWorkUtils/libs/miglayout.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbindingLinux.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbindingMac.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/MyJDownloaderClient"/>
<classpathentry kind="lib" path="ressourcen/libs/jna_platform.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/cling-core.jar" sourcepath="C:/Users/Thomas/Desktop/cling-distribution-2.0.1">
<attributes>
<attribute name="source_encoding" value="UTF-8"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/cling-support.jar">
<attributes>
<attribute name="source_encoding" value="UTF-8"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-http.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-util.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-xml.jar"/>
<classpathentry kind="lib" path="/AppWorkUtils/libs/proxyVole.jar" sourcepath="/ProxyVole"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaAluOxide.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlueLight.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaClassy.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jsyntaxpane.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sqljet.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sequence-library.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/svnkit.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/antlr-runtime.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaPlain.jar"/>
<classpathentry kind="lib" path="/AppWorkUtils/libs/svgSalamander.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/image4j.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/Filters.jar" sourcepath="ressourcen/code-ressourcen/Filter_src.zip"/>
<classpathentry kind="lib" path="ressourcen/libs/htmlunit-core-js.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/js.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/zip4j.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/bcpkix-jdk15on.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/bcprov-jdk15on.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/bctls-jdk15on.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/flatlaf.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jackson-annotations.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jackson-core.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jackson-databind.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="jd/plugins/optional/neembuu/|jd/plugins/optional/remoteserv/|jd/plugins/optional/remoteserv/|org/jdownloader/extensions/langfileeditor/" kind="src" path="src"/>
<classpathentry kind="src" path="src-closed"/>
<classpathentry kind="src" path="translations"/>
<classpathentry kind="src" path="themes"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="jd/ressourcen/libs/dbus"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/irclib.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/synthetica.jar" sourcepath="C:/Users/Thomas/Downloads/synthetica.src.2.zip">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/jd/ressourcen/code-ressourcen/synthetica_docs.zip!/"/>
<attribute name="source_encoding" value="UTF-8"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlackMoon.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlackStar.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlueIce.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlueMoon.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlueSteel.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaMauveMetallic.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaOrangeMetallic.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaSilverMoon.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaSimple2D.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaSkyMetallic.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaWhiteVision.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jna.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlackEye.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaGreenDream.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/dbus/debug-disable.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/dbus/hexdump.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/dbus/libdbus-java.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/dbus/unix.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbinding.jar"/>
<classpathentry kind="lib" path="ressourcen/libs_ext/AppleJavaExtensions.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/JDBrowser"/>
<classpathentry combineaccessrules="false" kind="src" path="/AppWorkUtils"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbindingWin.jar"/>
<classpathentry kind="lib" path="/AppWorkUtils/libs/miglayout.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbindingLinux.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sevenzipjbindingMac.jar"/>
<classpathentry combineaccessrules="false" kind="src" path="/MyJDownloaderClient"/>
<classpathentry kind="lib" path="ressourcen/libs/jna_platform.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/cling-core.jar" sourcepath="C:/Users/Thomas/Desktop/cling-distribution-2.0.1">
<attributes>
<attribute name="source_encoding" value="UTF-8"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/cling-support.jar">
<attributes>
<attribute name="source_encoding" value="UTF-8"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-http.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-util.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/UPNP/seamless-xml.jar"/>
<classpathentry kind="lib" path="/AppWorkUtils/libs/proxyVole.jar" sourcepath="/ProxyVole"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaAluOxide.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaBlueLight.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaClassy.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jsyntaxpane.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sqljet.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/sequence-library.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/svnkit.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/antlr-runtime.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/syntheticaPlain.jar"/>
<classpathentry kind="lib" path="/AppWorkUtils/libs/svgSalamander.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/image4j.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/Filters.jar" sourcepath="ressourcen/code-ressourcen/Filter_src.zip"/>
<classpathentry kind="lib" path="ressourcen/libs/htmlunit-core-js.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/js.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/zip4j.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/bcpkix-jdk15on.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/bcprov-jdk15on.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/bctls-jdk15on.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/laf/flatlaf.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jackson-annotations.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jackson-core.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/jackson-databind.jar"/>
<classpathentry kind="lib" path="ressourcen/libs/bcutil-jdk15on.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -1,11 +1,14 @@
package jd.plugins.hoster;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jd.PluginWrapper;
import jd.config.ConfigContainer;
import jd.config.ConfigEntry;
import jd.http.Browser;
import jd.http.RandomUserAgent;
import jd.http.URLConnectionAdapter;
import jd.nutils.encoding.Encoding;
@ -20,7 +23,12 @@ import jd.plugins.PluginForHost;
import jd.plugins.components.PluginJSonUtils;
import jd.utils.locale.JDL;
import org.appwork.storage.JSonStorage;
import org.appwork.storage.TypeRef;
import org.appwork.utils.StringUtils;
import org.jdownloader.plugins.components.config.RedtubeConfig;
import org.jdownloader.plugins.components.config.RedtubeConfig.PreferredStreamQuality;
import org.jdownloader.plugins.config.PluginJsonConfig;
import org.jdownloader.scripting.JavaScriptEngineFactory;
@HostPlugin(revision = "$Revision$", interfaceVersion = 2, names = { "redtube.com" }, urls = { "https?://(?:www\\.|[a-z]{2}\\.)?(?:redtube\\.(?:cn\\.com|com|tv|com\\.br)/|embed\\.redtube\\.(?:cn\\.com|com|tv|com\\.br)/[^<>\"]*?\\?id=)(\\d{4,})" })
@ -113,22 +121,72 @@ public class RedTubeCom extends PluginForHost {
final String playervars = br.getRegex("playervars: (.+?\\}),\n").getMatch(0);
if (playervars != null) {
final Map<String, Object> values = (Map<String, Object>) JavaScriptEngineFactory.jsonToJavaObject(playervars);
final List<Object> entries = (List<Object>) values.get("mediaDefinitions");
for (Object entry : entries) {
final Map<String, Object> e = (Map<String, Object>) entry;
String videoUrl = (String) e.get("videoUrl");
// maybe 1080p premium only. free is ""
if (StringUtils.isNotEmpty(videoUrl)) {
dllink = videoUrl;
long downloadSize = getDownloadSize();
if (downloadSize != -1) {
link.setDownloadSize(downloadSize);
}
List<HashMap<String, Object>> list = (List<HashMap<String, Object>>) values.get("mediaDefinitions");
for (Map<String, Object> entry : list) {
final String videoUrl = (String) entry.get("videoUrl");
final String format = (String) entry.get("format");
if (StringUtils.isEmpty(videoUrl)) {
continue;
} else if (StringUtils.equals("mp4", format)) {
final Browser brc = br.cloneBrowser();
brc.getPage(videoUrl);
list = JSonStorage.restoreFromString(brc.toString(), TypeRef.LIST_HASHMAP);
break;
}
}
final String userPreferredQuality = getPreferredStreamQuality();
if (list != null) {
int qualityMax = 0;
for (Object entry : list) {
Map<String, Object> video = (Map<String, Object>) entry;
final String videoUrl = (String) video.get("videoUrl");
final Object quality = video.get("quality");
if (StringUtils.isEmpty(videoUrl)) {
continue;
} else if (quality == null) {
continue;
}
final Number fileSize = (Number) video.get("videoSize");
final String qualityTempStr = (String) quality;
if (StringUtils.equals(qualityTempStr, userPreferredQuality)) {
logger.info("Found user preferred quality: " + userPreferredQuality);
if (fileSize != null) {
link.setDownloadSize(fileSize.longValue());
}
dllink = videoUrl;
break;
}
final int qualityTemp = Integer.parseInt(qualityTempStr);
if (qualityTemp > qualityMax) {
if (fileSize != null) {
link.setDownloadSize(fileSize.longValue());
}
qualityMax = qualityTemp;
dllink = videoUrl;
}
}
if (dllink != null) {
final Browser brc = br.cloneBrowser();
URLConnectionAdapter con = null;
try {
con = brc.openHeadConnection(dllink);
if (looksLikeDownloadableContent(con)) {
if (con.getCompleteContentLength() > 0) {
link.setDownloadSize(con.getCompleteContentLength());
}
} else {
server_issues = true;
}
} finally {
if (con != null) {
con.disconnect();
}
}
}
}
}
if (dllink == null) {
// old handling
dllink = br.getRegex("source src=\"(http.*?)(\"|%3D%22)").getMatch(0);
if (dllink != null && dllink.contains("&amp;")) {
dllink = dllink.replace("&amp;", "&");
@ -184,23 +242,6 @@ public class RedTubeCom extends PluginForHost {
return AvailableStatus.TRUE;
}
private long getDownloadSize() throws Exception {
long result = -1;
URLConnectionAdapter con = null;
try {
con = br.openHeadConnection(dllink);
if (!con.getContentType().contains("html")) {
result = br.getHttpConnection().getLongContentLength();
}
} finally {
try {
con.disconnect();
} catch (final Throwable e) {
}
}
return result;
}
@Override
public void handleFree(DownloadLink link) throws Exception {
this.setBrowserExclusive();
@ -213,13 +254,44 @@ public class RedTubeCom extends PluginForHost {
throw new PluginException(LinkStatus.ERROR_PLUGIN_DEFECT);
}
dl = jd.plugins.BrowserAdapter.openDownload(br, link, dllink, true, 0);
if (dl.getConnection().getContentType().contains("html")) {
dl.getConnection().disconnect();
if (!looksLikeDownloadableContent(dl.getConnection())) {
try {
br.followConnection(true);
} catch (IOException e) {
logger.log(e);
}
throw new PluginException(LinkStatus.ERROR_FILE_NOT_FOUND);
}
dl.startDownload();
}
private String getPreferredStreamQuality() {
final RedtubeConfig cfg = PluginJsonConfig.get(this.getConfigInterface());
final PreferredStreamQuality quality = cfg.getPreferredStreamQuality();
switch (quality) {
case BEST:
default:
return null;
case Q2160P:
return "2160";
case Q1080P:
return "1080";
case Q720P:
return "720";
case Q480P:
return "480";
case Q360P:
return "360";
case Q240P:
return "240";
}
}
@Override
public Class<? extends RedtubeConfig> getConfigInterface() {
return RedtubeConfig.class;
}
@Override
public void reset() {
}

View File

@ -201,8 +201,8 @@ public class YouPornCom extends PluginForHost {
/* Find highest quality */
int qualityMax = 0;
/* 2020-07-02: Try to obey users' selected quality in this block only */
String filesize = null;
final String mediaDefinition = br.getRegex("(?:video\\.)?mediaDefinition\\s*[=:]\\s*(\\[.*?\\]);").getMatch(0);
String fileSizeString = null;
if (mediaDefinition != null) {
ArrayList<HashMap<String, Object>> list = JSonStorage.restoreFromString(mediaDefinition, TypeRef.LIST_HASHMAP);
for (Map<String, Object> entry : list) {
@ -233,7 +233,8 @@ public class YouPornCom extends PluginForHost {
final String qualityTempStr = (String) quality;
if (StringUtils.equals(qualityTempStr, userPreferredQuality)) {
logger.info("Found user preferred quality: " + userPreferredQuality);
if (filesize != null) {
if (fileSize != null) {
fileSizeString = fileSize.toString();
link.setDownloadSize(fileSize.longValue());
}
dllink = videoUrl;
@ -241,7 +242,8 @@ public class YouPornCom extends PluginForHost {
}
final int qualityTemp = Integer.parseInt(qualityTempStr);
if (qualityTemp > qualityMax) {
if (filesize != null) {
if (fileSize != null) {
fileSizeString = fileSize.toString();
link.setDownloadSize(fileSize.longValue());
}
qualityMax = qualityTemp;
@ -265,7 +267,7 @@ public class YouPornCom extends PluginForHost {
this.dllink = new Regex(html, "(https?://[^'\"]+\\d+p[^'\"]+\\.mp4[^\\'\"\\|]+)").getMatch(0);
if (this.dllink != null) {
/* Only attempt to grab filesize if it corresponds to the current videoquality! */
filesize = new Regex(html, "class=\\'downloadsize\\'>\\((\\d+[^<>\"]+)\\)").getMatch(0);
fileSizeString = new Regex(html, "class=\\'downloadsize\\'>\\((\\d+[^<>\"]+)\\)").getMatch(0);
}
}
}
@ -294,8 +296,8 @@ public class YouPornCom extends PluginForHost {
dllink = dllink.replace("&amp;", "&");
}
link.setFinalFileName(filename + defaultEXT);
if (filesize != null) {
link.setDownloadSize(SizeFormatter.getSize(filesize));
if (fileSizeString != null) {
link.setDownloadSize(SizeFormatter.getSize(fileSizeString));
} else if (dllink != null) {
URLConnectionAdapter con = null;
try {

View File

@ -0,0 +1,66 @@
package org.jdownloader.plugins.components.config;
import org.appwork.storage.config.annotations.AboutConfig;
import org.appwork.storage.config.annotations.DefaultEnumValue;
import org.appwork.storage.config.annotations.DescriptionForConfigEntry;
import org.appwork.storage.config.annotations.LabelInterface;
import org.jdownloader.plugins.config.Order;
import org.jdownloader.plugins.config.PluginConfigInterface;
import org.jdownloader.plugins.config.PluginHost;
import org.jdownloader.plugins.config.Type;
@PluginHost(host = "redtube.com", type = Type.HOSTER)
public interface RedtubeConfig extends PluginConfigInterface {
public static enum PreferredStreamQuality implements LabelInterface {
BEST {
@Override
public String getLabel() {
return "Best";
}
},
Q240P {
@Override
public String getLabel() {
return "240p";
}
},
Q360P {
@Override
public String getLabel() {
return "360p";
}
},
Q480P {
@Override
public String getLabel() {
return "480p";
}
},
Q720P {
@Override
public String getLabel() {
return "720p";
}
},
Q1080P {
@Override
public String getLabel() {
return "1080p";
}
},
Q2160P {
@Override
public String getLabel() {
return "2160p (4k)";
}
};
}
@AboutConfig
@DefaultEnumValue("BEST")
@DescriptionForConfigEntry("If your preferred stream quality is not found, best quality will be downloaded instead.")
@Order(100)
PreferredStreamQuality getPreferredStreamQuality();
void setPreferredStreamQuality(PreferredStreamQuality quality);
}