forked from recloudstream/cloudstream
		
	added subtitle encoding
This commit is contained in:
		
							parent
							
								
									4701def2be
								
							
						
					
					
						commit
						fbf8a758a3
					
				
					 5 changed files with 209 additions and 37 deletions
				
			
		|  | @ -1,6 +1,8 @@ | ||||||
| package com.lagradost.cloudstream3.ui.player | package com.lagradost.cloudstream3.ui.player | ||||||
| 
 | 
 | ||||||
|  | import android.content.Context | ||||||
| import android.util.Log | import android.util.Log | ||||||
|  | import androidx.preference.PreferenceManager | ||||||
| import com.google.android.exoplayer2.Format | import com.google.android.exoplayer2.Format | ||||||
| import com.google.android.exoplayer2.text.SubtitleDecoder | import com.google.android.exoplayer2.text.SubtitleDecoder | ||||||
| import com.google.android.exoplayer2.text.SubtitleDecoderFactory | import com.google.android.exoplayer2.text.SubtitleDecoderFactory | ||||||
|  | @ -11,15 +13,29 @@ import com.google.android.exoplayer2.text.subrip.SubripDecoder | ||||||
| import com.google.android.exoplayer2.text.ttml.TtmlDecoder | import com.google.android.exoplayer2.text.ttml.TtmlDecoder | ||||||
| import com.google.android.exoplayer2.text.webvtt.WebvttDecoder | import com.google.android.exoplayer2.text.webvtt.WebvttDecoder | ||||||
| import com.google.android.exoplayer2.util.MimeTypes | import com.google.android.exoplayer2.util.MimeTypes | ||||||
|  | import com.lagradost.cloudstream3.R | ||||||
| import com.lagradost.cloudstream3.mvvm.logError | import com.lagradost.cloudstream3.mvvm.logError | ||||||
| import org.mozilla.universalchardet.UniversalDetector | import org.mozilla.universalchardet.UniversalDetector | ||||||
| import java.nio.ByteBuffer | import java.nio.ByteBuffer | ||||||
| 
 | 
 | ||||||
| class CustomDecoder : SubtitleDecoder { | class CustomDecoder : SubtitleDecoder { | ||||||
|     companion object { |     companion object { | ||||||
|  |         fun updateForcedEncoding(context: Context) { | ||||||
|  |             val settingsManager = PreferenceManager.getDefaultSharedPreferences(context) | ||||||
|  |             val value = settingsManager.getString( | ||||||
|  |                 context.getString(R.string.subtitles_encoding_key), | ||||||
|  |                 null | ||||||
|  |             ) | ||||||
|  |             overrideEncoding = if (value.isNullOrBlank()) { | ||||||
|  |                 null | ||||||
|  |             } else { | ||||||
|  |                 value | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         private const val UTF_8 = "UTF-8" |         private const val UTF_8 = "UTF-8" | ||||||
|         private const val TAG = "CustomDecoder" |         private const val TAG = "CustomDecoder" | ||||||
|         private var overrideEncoding: String? = null //TODO MAKE SETTING |         private var overrideEncoding: String? = null | ||||||
|         var regexSubtitlesToRemoveCaptions = false |         var regexSubtitlesToRemoveCaptions = false | ||||||
|         val bloatRegex = |         val bloatRegex = | ||||||
|             listOf( |             listOf( | ||||||
|  | @ -69,7 +85,7 @@ class CustomDecoder : SubtitleDecoder { | ||||||
|                     // this way we read the subtitle file and decide what decoder to use instead of relying on mimetype |                     // this way we read the subtitle file and decide what decoder to use instead of relying on mimetype | ||||||
|                     Log.i(TAG, "Got data from queueInputBuffer") |                     Log.i(TAG, "Got data from queueInputBuffer") | ||||||
| 
 | 
 | ||||||
|                     var str = try { |                     var (str, charset) = try { | ||||||
|                         data.position(0) |                         data.position(0) | ||||||
|                         val fullDataArr = ByteArray(data.remaining()) |                         val fullDataArr = ByteArray(data.remaining()) | ||||||
|                         data.get(fullDataArr) |                         data.get(fullDataArr) | ||||||
|  | @ -80,7 +96,7 @@ class CustomDecoder : SubtitleDecoder { | ||||||
|                                 detector.handleData(fullDataArr, 0, fullDataArr.size) |                                 detector.handleData(fullDataArr, 0, fullDataArr.size) | ||||||
|                                 detector.dataEnd() |                                 detector.dataEnd() | ||||||
| 
 | 
 | ||||||
|                                 detector.detectedCharset // "windows-1256" adabic |                                 detector.detectedCharset // "windows-1256" | ||||||
|                             } |                             } | ||||||
| 
 | 
 | ||||||
|                             Log.i( |                             Log.i( | ||||||
|  | @ -93,14 +109,24 @@ class CustomDecoder : SubtitleDecoder { | ||||||
|                             logError(e) |                             logError(e) | ||||||
|                             UTF_8 |                             UTF_8 | ||||||
|                         } |                         } | ||||||
|                         var fullStr = try { | 
 | ||||||
|                             String(fullDataArr, charset(encoding)) |                         var (fullStr, charset) = try { | ||||||
|  |                             val set = charset(encoding) | ||||||
|  |                             Pair(String(fullDataArr, set), set) | ||||||
|                         } catch (e: Exception) { |                         } catch (e: Exception) { | ||||||
|                             Log.e(TAG, "Failed to parse using encoding $encoding") |                             Log.e(TAG, "Failed to parse using encoding $encoding") | ||||||
|                             logError(e) |                             logError(e) | ||||||
|                             fullDataArr.decodeToString() |                             Pair(fullDataArr.decodeToString(), charset(UTF_8)) | ||||||
|                         } |                         } | ||||||
| 
 | 
 | ||||||
|  |                         bloatRegex.forEach { rgx -> | ||||||
|  |                             fullStr = fullStr.replace(rgx, "\n") | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         fullStr.replace(Regex("(\r\n|\r|\n){2,}"), "\n") | ||||||
|  |                         // fullStr = "1\n00:00:01,616 --> 00:00:40,200\n" + | ||||||
|  |                         //         "تــــرجــمة" | ||||||
|  | 
 | ||||||
|                         Log.i( |                         Log.i( | ||||||
|                             TAG, |                             TAG, | ||||||
|                             "Encoded Text start: " + fullStr.substring( |                             "Encoded Text start: " + fullStr.substring( | ||||||
|  | @ -108,14 +134,7 @@ class CustomDecoder : SubtitleDecoder { | ||||||
|                                 minOf(fullStr.length, 300) |                                 minOf(fullStr.length, 300) | ||||||
|                             ) |                             ) | ||||||
|                         ) |                         ) | ||||||
| 
 |                         Pair(fullStr, charset) | ||||||
|                         bloatRegex.forEach { rgx -> |  | ||||||
|                             fullStr = fullStr.replace(rgx, "\n") |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         fullStr.replace(Regex("(\r\n|\r|\n){2,}"), "\n") |  | ||||||
| 
 |  | ||||||
|                         fullStr |  | ||||||
|                     } catch (e: Exception) { |                     } catch (e: Exception) { | ||||||
|                         Log.e(TAG, "Failed to parse text returning plain data") |                         Log.e(TAG, "Failed to parse text returning plain data") | ||||||
|                         logError(e) |                         logError(e) | ||||||
|  | @ -149,7 +168,7 @@ class CustomDecoder : SubtitleDecoder { | ||||||
|                                     } |                                     } | ||||||
|                                 } |                                 } | ||||||
| 
 | 
 | ||||||
|                                 buff.data = ByteBuffer.wrap(str.toByteArray()) |                                 buff.data = ByteBuffer.wrap(str.toByteArray(charset = charset)) | ||||||
| 
 | 
 | ||||||
|                                 decoder.queueInputBuffer(buff) |                                 decoder.queueInputBuffer(buff) | ||||||
|                                 Log.i( |                                 Log.i( | ||||||
|  |  | ||||||
|  | @ -15,7 +15,6 @@ import androidx.core.view.isVisible | ||||||
| import androidx.lifecycle.ViewModelProvider | import androidx.lifecycle.ViewModelProvider | ||||||
| import androidx.preference.PreferenceManager | import androidx.preference.PreferenceManager | ||||||
| import com.google.android.exoplayer2.util.MimeTypes | import com.google.android.exoplayer2.util.MimeTypes | ||||||
| import com.google.android.material.button.MaterialButton |  | ||||||
| import com.hippo.unifile.UniFile | import com.hippo.unifile.UniFile | ||||||
| import com.lagradost.cloudstream3.* | import com.lagradost.cloudstream3.* | ||||||
| import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull | import com.lagradost.cloudstream3.APIHolder.getApiFromNameNull | ||||||
|  | @ -24,6 +23,7 @@ import com.lagradost.cloudstream3.mvvm.Resource | ||||||
| import com.lagradost.cloudstream3.mvvm.logError | import com.lagradost.cloudstream3.mvvm.logError | ||||||
| import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | import com.lagradost.cloudstream3.mvvm.normalSafeApiCall | ||||||
| import com.lagradost.cloudstream3.mvvm.observe | import com.lagradost.cloudstream3.mvvm.observe | ||||||
|  | import com.lagradost.cloudstream3.ui.player.CustomDecoder.Companion.updateForcedEncoding | ||||||
| import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType | import com.lagradost.cloudstream3.ui.player.PlayerSubtitleHelper.Companion.toSubtitleMimeType | ||||||
| import com.lagradost.cloudstream3.ui.result.ResultEpisode | import com.lagradost.cloudstream3.ui.result.ResultEpisode | ||||||
| import com.lagradost.cloudstream3.ui.result.ResultFragment | import com.lagradost.cloudstream3.ui.result.ResultFragment | ||||||
|  | @ -32,11 +32,13 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSet | ||||||
| import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment | import com.lagradost.cloudstream3.ui.subtitles.SubtitlesFragment | ||||||
| import com.lagradost.cloudstream3.utils.* | import com.lagradost.cloudstream3.utils.* | ||||||
| import com.lagradost.cloudstream3.utils.Coroutines.ioSafe | import com.lagradost.cloudstream3.utils.Coroutines.ioSafe | ||||||
|  | import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showDialog | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe | import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.hideSystemUI | import com.lagradost.cloudstream3.utils.UIHelper.hideSystemUI | ||||||
| import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage | import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage | ||||||
| import kotlinx.android.synthetic.main.fragment_player.* | import kotlinx.android.synthetic.main.fragment_player.* | ||||||
| import kotlinx.android.synthetic.main.player_custom_layout.* | import kotlinx.android.synthetic.main.player_custom_layout.* | ||||||
|  | import kotlinx.android.synthetic.main.player_select_source_and_subs.* | ||||||
| import kotlinx.coroutines.Job | import kotlinx.coroutines.Job | ||||||
| 
 | 
 | ||||||
| class GeneratorPlayer : FullScreenPlayer() { | class GeneratorPlayer : FullScreenPlayer() { | ||||||
|  | @ -241,14 +243,8 @@ class GeneratorPlayer : FullScreenPlayer() { | ||||||
|                 val sourceDialog = sourceBuilder.create() |                 val sourceDialog = sourceBuilder.create() | ||||||
|                 selectSourceDialog = sourceDialog |                 selectSourceDialog = sourceDialog | ||||||
|                 sourceDialog.show() |                 sourceDialog.show() | ||||||
|                 val providerList = |                 val providerList = sourceDialog.sort_providers | ||||||
|                     sourceDialog.findViewById<ListView>(R.id.sort_providers)!! |                 val subtitleList = sourceDialog.sort_subtitles | ||||||
|                 val subtitleList = |  | ||||||
|                     sourceDialog.findViewById<ListView>(R.id.sort_subtitles)!! |  | ||||||
|                 val applyButton = |  | ||||||
|                     sourceDialog.findViewById<MaterialButton>(R.id.apply_btt)!! |  | ||||||
|                 val cancelButton = |  | ||||||
|                     sourceDialog.findViewById<MaterialButton>(R.id.cancel_btt)!! |  | ||||||
| 
 | 
 | ||||||
|                 val footer: TextView = |                 val footer: TextView = | ||||||
|                     layoutInflater.inflate(R.layout.sort_bottom_footer_add_choice, null) as TextView |                     layoutInflater.inflate(R.layout.sort_bottom_footer_add_choice, null) as TextView | ||||||
|  | @ -314,11 +310,56 @@ class GeneratorPlayer : FullScreenPlayer() { | ||||||
|                     subtitleList.setItemChecked(which, true) |                     subtitleList.setItemChecked(which, true) | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 cancelButton.setOnClickListener { |                 sourceDialog.cancel_btt?.setOnClickListener { | ||||||
|                     sourceDialog.dismissSafe(activity) |                     sourceDialog.dismissSafe(activity) | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 applyButton.setOnClickListener { |                 sourceDialog.subtitles_encoding_format?.apply { | ||||||
|  |                     val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx) | ||||||
|  | 
 | ||||||
|  |                     val prefNames = ctx.resources.getStringArray(R.array.subtitles_encoding_list) | ||||||
|  |                     val prefValues = ctx.resources.getStringArray(R.array.subtitles_encoding_values) | ||||||
|  | 
 | ||||||
|  |                     val value = settingsManager.getString( | ||||||
|  |                         ctx.getString(R.string.subtitles_encoding_key), | ||||||
|  |                         null | ||||||
|  |                     ) | ||||||
|  |                     val index = prefValues.indexOf(value) | ||||||
|  |                     text = prefNames[if(index == -1) 0 else index] | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 sourceDialog.subtitles_click_settings?.setOnClickListener { | ||||||
|  |                     val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx) | ||||||
|  | 
 | ||||||
|  |                     val prefNames = ctx.resources.getStringArray(R.array.subtitles_encoding_list) | ||||||
|  |                     val prefValues = ctx.resources.getStringArray(R.array.subtitles_encoding_values) | ||||||
|  | 
 | ||||||
|  |                     val currentPrefMedia = | ||||||
|  |                         settingsManager.getString( | ||||||
|  |                             getString(R.string.subtitles_encoding_key), | ||||||
|  |                             null | ||||||
|  |                         ) | ||||||
|  | 
 | ||||||
|  |                     val index = prefValues.indexOf(currentPrefMedia) | ||||||
|  |                     sourceDialog.dismissSafe(activity) | ||||||
|  |                     activity?.showDialog( | ||||||
|  |                         prefNames.toList(), | ||||||
|  |                         if(index == -1) 0 else index, | ||||||
|  |                         ctx.getString(R.string.subtitles_encoding), | ||||||
|  |                         true, | ||||||
|  |                         {}) { | ||||||
|  |                         settingsManager.edit() | ||||||
|  |                             .putString( | ||||||
|  |                                 ctx.getString(R.string.subtitles_encoding_key), | ||||||
|  |                                 prefValues[it] | ||||||
|  |                             ) | ||||||
|  |                             .apply() | ||||||
|  |                         println("FORCED ENCODING: ${prefValues[it]}") | ||||||
|  |                         updateForcedEncoding(ctx) | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 sourceDialog.apply_btt?.setOnClickListener { | ||||||
|                     var init = false |                     var init = false | ||||||
|                     if (sourceIndex != startSource) { |                     if (sourceIndex != startSource) { | ||||||
|                         init = true |                         init = true | ||||||
|  | @ -668,6 +709,7 @@ class GeneratorPlayer : FullScreenPlayer() { | ||||||
|             val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx) |             val settingsManager = PreferenceManager.getDefaultSharedPreferences(ctx) | ||||||
|             titleRez = settingsManager.getInt(getString(R.string.prefer_limit_title_rez_key), 3) |             titleRez = settingsManager.getInt(getString(R.string.prefer_limit_title_rez_key), 3) | ||||||
|             limitTitle = settingsManager.getInt(getString(R.string.prefer_limit_title_key), 0) |             limitTitle = settingsManager.getInt(getString(R.string.prefer_limit_title_key), 0) | ||||||
|  |             updateForcedEncoding(ctx) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         unwrapBundle(savedInstanceState) |         unwrapBundle(savedInstanceState) | ||||||
|  |  | ||||||
|  | @ -62,19 +62,37 @@ | ||||||
|                     android:orientation="horizontal" |                     android:orientation="horizontal" | ||||||
|                     tools:ignore="UseCompoundDrawables"> |                     tools:ignore="UseCompoundDrawables"> | ||||||
| 
 | 
 | ||||||
|                 <TextView |                 <LinearLayout | ||||||
|                         android:layout_width="match_parent" |                         android:foreground="?attr/selectableItemBackgroundBorderless" | ||||||
|                         android:layout_height="wrap_content" |                         android:id="@+id/subtitles_click_settings" | ||||||
|                         android:layout_rowWeight="1" |                         android:layout_rowWeight="1" | ||||||
|                         android:layout_marginTop="10dp" |  | ||||||
|                         android:paddingStart="?android:attr/listPreferredItemPaddingStart" |  | ||||||
|                         android:paddingTop="10dp" |                         android:paddingTop="10dp" | ||||||
|                         android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" |  | ||||||
|                         android:paddingBottom="10dp" |                         android:paddingBottom="10dp" | ||||||
|                         android:text="@string/pick_subtitle" |                         android:layout_marginTop="10dp" | ||||||
|                         android:textColor="?attr/textColor" |                         android:orientation="horizontal" | ||||||
|                         android:textSize="20sp" |                         android:layout_width="match_parent" | ||||||
|                         android:textStyle="bold" /> |                         android:layout_height="wrap_content"> | ||||||
|  | 
 | ||||||
|  |                     <TextView | ||||||
|  |                             android:layout_width="wrap_content" | ||||||
|  |                             android:layout_height="wrap_content" | ||||||
|  |                             android:paddingStart="?android:attr/listPreferredItemPaddingStart" | ||||||
|  |                             android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" | ||||||
|  |                             android:text="@string/pick_subtitle" | ||||||
|  |                             android:textColor="?attr/textColor" | ||||||
|  |                             android:textSize="20sp" | ||||||
|  |                             android:textStyle="bold" /> | ||||||
|  | 
 | ||||||
|  |                     <TextView | ||||||
|  |                             android:textSize="15sp" | ||||||
|  |                             android:id="@+id/subtitles_encoding_format" | ||||||
|  |                             android:textColor="?attr/textColor" | ||||||
|  |                             android:layout_gravity="center" | ||||||
|  |                             android:gravity="center" | ||||||
|  |                             tools:text="Thai (TIS 620-2533/ISO 8859-11)" | ||||||
|  |                             android:layout_width="wrap_content" | ||||||
|  |                             android:layout_height="wrap_content" /> | ||||||
|  |                 </LinearLayout> | ||||||
| 
 | 
 | ||||||
|                 <ImageView |                 <ImageView | ||||||
|                         android:layout_width="25dp" |                         android:layout_width="25dp" | ||||||
|  | @ -112,6 +130,7 @@ | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="60dp"> |             android:layout_height="60dp"> | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|         <com.google.android.material.button.MaterialButton |         <com.google.android.material.button.MaterialButton | ||||||
|                 style="@style/WhiteButton" |                 style="@style/WhiteButton" | ||||||
|                 android:layout_gravity="center_vertical|end" |                 android:layout_gravity="center_vertical|end" | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||||
| <resources> | <resources xmlns:tools="http://schemas.android.com/tools"> | ||||||
|     <array name="cast_mini_controller_control_buttons"> |     <array name="cast_mini_controller_control_buttons"> | ||||||
|         <item>@id/cast_button_type_rewind_30_seconds</item> |         <item>@id/cast_button_type_rewind_30_seconds</item> | ||||||
|         <item>@id/cast_button_type_play_pause_toggle</item> |         <item>@id/cast_button_type_play_pause_toggle</item> | ||||||
|  | @ -269,4 +269,94 @@ | ||||||
|         <item>Amoled</item> |         <item>Amoled</item> | ||||||
|         <item>Light</item> |         <item>Light</item> | ||||||
|     </string-array> |     </string-array> | ||||||
|  | 
 | ||||||
|  |     <!--https://github.com/videolan/vlc-android/blob/72ccfb93db027b49855760001d1a930fa657c5a8/application/resources/src/main/res/values/arrays.xml#L266--> | ||||||
|  |     <string-array name="subtitles_encoding_list" tools:ignore="TypographyDashes"> | ||||||
|  |         <item>@string/automatic</item> | ||||||
|  |         <item>Universal (UTF-8)</item> | ||||||
|  |         <item>Universal (UTF-16)</item> | ||||||
|  |         <item>Universal (big endian UTF-16)</item> | ||||||
|  |         <item>Universal (little endian UTF-16)</item> | ||||||
|  |         <item>Universal, Chinese (GB18030)</item> | ||||||
|  |         <item>Western European (Latin-9)</item> | ||||||
|  |         <item>Western European (Windows-1252)</item> | ||||||
|  |         <item>Western European (IBM 00850)</item> | ||||||
|  |         <item>Eastern European (Latin-2)</item> | ||||||
|  |         <item>Eastern European (Windows-1250)</item> | ||||||
|  |         <item>Esperanto (Latin-3)</item> | ||||||
|  |         <item>Nordic (Latin-6)</item> | ||||||
|  |         <item>Cyrillic (Windows-1251)</item> | ||||||
|  |         <item>Russian (KOI8-R)</item> | ||||||
|  |         <item>Ukrainian (KOI8-U)</item> | ||||||
|  |         <item>Arabic (ISO 8859-6)</item> | ||||||
|  |         <item>Arabic (Windows-1256)</item> | ||||||
|  |         <item>Greek (ISO 8859-7)</item> | ||||||
|  |         <item>Greek (Windows-1253)</item> | ||||||
|  |         <item>Hebrew (ISO 8859-8)</item> | ||||||
|  |         <item>Hebrew (Windows-1255)</item> | ||||||
|  |         <item>Turkish (ISO 8859-9)</item> | ||||||
|  |         <item>Turkish (Windows-1254)</item> | ||||||
|  |         <item>Thai (TIS 620-2533/ISO 8859-11)</item> | ||||||
|  |         <item>Thai (Windows-874)</item> | ||||||
|  |         <item>Baltic (Latin-7)</item> | ||||||
|  |         <item>Baltic (Windows-1257)</item> | ||||||
|  |         <item>Celtic (Latin-8)</item> | ||||||
|  |         <item>South-Eastern European (Latin-10)</item> | ||||||
|  |         <item>Simplified Chinese (ISO-2022-CN-EXT)</item> | ||||||
|  |         <item>Simplified Chinese Unix (EUC-CN)</item> | ||||||
|  |         <item>Japanese (7-bits JIS/ISO-2022-JP-2)</item> | ||||||
|  |         <item>Japanese Unix (EUC-JP)</item> | ||||||
|  |         <item>Japanese (Shift JIS)</item> | ||||||
|  |         <item>Korean (EUC-KR/CP949)</item> | ||||||
|  |         <item>Korean (ISO-2022-KR)</item> | ||||||
|  |         <item>Traditional Chinese (Big5)</item> | ||||||
|  |         <item>Traditional Chinese Unix (EUC-TW)</item> | ||||||
|  |         <item>Hong-Kong Supplementary (HKSCS)</item> | ||||||
|  |         <item>Vietnamese (VISCII)</item> | ||||||
|  |         <item>Vietnamese (Windows-1258)</item> | ||||||
|  |     </string-array> | ||||||
|  |     <string-array name="subtitles_encoding_values" translatable="false" tools:ignore="TypographyDashes"> | ||||||
|  |         <item></item> | ||||||
|  |         <item>UTF-8</item> | ||||||
|  |         <item>UTF-16</item> | ||||||
|  |         <item>UTF-16BE</item> | ||||||
|  |         <item>UTF-16LE</item> | ||||||
|  |         <item>GB18030</item> | ||||||
|  |         <item>ISO-8859-15</item> | ||||||
|  |         <item>Windows-1252</item> | ||||||
|  |         <item>IBM850</item> | ||||||
|  |         <item>ISO-8859-2</item> | ||||||
|  |         <item>Windows-1250</item> | ||||||
|  |         <item>ISO-8859-3</item> | ||||||
|  |         <item>ISO-8859-10</item> | ||||||
|  |         <item>Windows-1251</item> | ||||||
|  |         <item>KOI8-R</item> | ||||||
|  |         <item>KOI8-U</item> | ||||||
|  |         <item>ISO-8859-6</item> | ||||||
|  |         <item>Windows-1256</item> | ||||||
|  |         <item>ISO-8859-7</item> | ||||||
|  |         <item>Windows-1253</item> | ||||||
|  |         <item>ISO-8859-8</item> | ||||||
|  |         <item>Windows-1255</item> | ||||||
|  |         <item>ISO-8859-9</item> | ||||||
|  |         <item>Windows-1254</item> | ||||||
|  |         <item>ISO-8859-11</item> | ||||||
|  |         <item>Windows-874</item> | ||||||
|  |         <item>ISO-8859-13</item> | ||||||
|  |         <item>Windows-1257</item> | ||||||
|  |         <item>ISO-8859-14</item> | ||||||
|  |         <item>ISO-8859-16</item> | ||||||
|  |         <item>ISO-2022-CN-EXT</item> | ||||||
|  |         <item>EUC-CN</item> | ||||||
|  |         <item>ISO-2022-JP-2</item> | ||||||
|  |         <item>EUC-JP</item> | ||||||
|  |         <item>Shift_JIS</item> | ||||||
|  |         <item>CP949</item> | ||||||
|  |         <item>ISO-2022-KR</item> | ||||||
|  |         <item>Big5</item> | ||||||
|  |         <item>ISO-2022-TW</item> | ||||||
|  |         <item>Big5-HKSCS</item> | ||||||
|  |         <item>VISCII</item> | ||||||
|  |         <item>Windows-1258</item> | ||||||
|  |     </string-array> | ||||||
| </resources> | </resources> | ||||||
|  |  | ||||||
|  | @ -51,6 +51,7 @@ | ||||||
|     <string name="show_logcat_key" translatable="false">show_logcat_key</string> |     <string name="show_logcat_key" translatable="false">show_logcat_key</string> | ||||||
|     <string name="bottom_title_key" translatable="false">bottom_title_key</string> |     <string name="bottom_title_key" translatable="false">bottom_title_key</string> | ||||||
|     <string name="poster_ui_key" translatable="false">poster_ui_key</string> |     <string name="poster_ui_key" translatable="false">poster_ui_key</string> | ||||||
|  |     <string name="subtitles_encoding_key" translatable="false">subtitles_encoding_key</string> | ||||||
| 
 | 
 | ||||||
|     <!-- FORMAT MIGHT TRANSLATE, WILL CAUSE CRASH IF APPLIED WRONG --> |     <!-- FORMAT MIGHT TRANSLATE, WILL CAUSE CRASH IF APPLIED WRONG --> | ||||||
|     <string name="extra_info_format" translatable="false" formatted="true">%d %s | %sMB</string> |     <string name="extra_info_format" translatable="false" formatted="true">%d %s | %sMB</string> | ||||||
|  | @ -418,6 +419,7 @@ | ||||||
|     <string name="provider_lang_settings">Provider languages</string> |     <string name="provider_lang_settings">Provider languages</string> | ||||||
|     <string name="app_layout">App Layout</string> |     <string name="app_layout">App Layout</string> | ||||||
|     <string name="preferred_media_settings">Preferred media</string> |     <string name="preferred_media_settings">Preferred media</string> | ||||||
|  |     <string name="subtitles_encoding">Subtitle encoding</string> | ||||||
|     <string name="category_preferred_media_and_lang">Preferred media and language</string> |     <string name="category_preferred_media_and_lang">Preferred media and language</string> | ||||||
|     <string name="category_ui">User interface</string> |     <string name="category_ui">User interface</string> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue