mirror of
				https://github.com/recloudstream/cloudstream.git
				synced 2024-08-15 01:53:11 +00:00 
			
		
		
		
	poc
This commit is contained in:
		
							parent
							
								
									afe82140fd
								
							
						
					
					
						commit
						49b905c089
					
				
					 6 changed files with 147 additions and 21 deletions
				
			
		|  | @ -261,7 +261,7 @@ dependencies { | ||||||
|     // color palette for images -> colors |     // color palette for images -> colors | ||||||
|     implementation("androidx.palette:palette-ktx:1.0.0") |     implementation("androidx.palette:palette-ktx:1.0.0") | ||||||
| 
 | 
 | ||||||
|     implementation("com.github.recloudstream:Aria2cStream:0.0.1") |     implementation("com.github.recloudstream:Aria2cStream:0.0.3") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| tasks.register("androidSourcesJar", Jar::class) { | tasks.register("androidSourcesJar", Jar::class) { | ||||||
|  |  | ||||||
|  | @ -1569,14 +1569,13 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | ||||||
| 
 | 
 | ||||||
|         //val defaultDirectory = "${filesDir.path}/torrent_tmp" |         //val defaultDirectory = "${filesDir.path}/torrent_tmp" | ||||||
|         //File(defaultDirectory).deleteRecursively() |         //File(defaultDirectory).deleteRecursively() | ||||||
|         navigate( |         /*navigate( | ||||||
|             R.id.global_to_navigation_player, GeneratorPlayer.newInstance( |             R.id.global_to_navigation_player, GeneratorPlayer.newInstance( | ||||||
|                 ExtractorLinkGenerator( |                 ExtractorLinkGenerator( | ||||||
|                     listOf( |                     listOf( | ||||||
|                         ExtractorLink( |                         ExtractorLink( | ||||||
|                             source = "", |                             source = "", | ||||||
|                             name = "hello world", |                             name = "hello world", | ||||||
|                             url = "", |  | ||||||
|                             "", |                             "", | ||||||
|                             Qualities.Unknown.value, |                             Qualities.Unknown.value, | ||||||
|                             type = INFER_TYPE |                             type = INFER_TYPE | ||||||
|  | @ -1585,7 +1584,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener { | ||||||
|                     emptyList() |                     emptyList() | ||||||
|                 ) |                 ) | ||||||
|             ) |             ) | ||||||
|         ) |         )*/ | ||||||
| 
 | 
 | ||||||
| //        Used to check current focus for TV | //        Used to check current focus for TV | ||||||
| //        main { | //        main { | ||||||
|  |  | ||||||
|  | @ -135,7 +135,7 @@ abstract class AbstractPlayerFragment( | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private fun updateIsPlaying(wasPlaying : CSPlayerLoading, |     open fun updateIsPlaying(wasPlaying : CSPlayerLoading, | ||||||
|                                 isPlaying : CSPlayerLoading) { |                                 isPlaying : CSPlayerLoading) { | ||||||
|         val isPlayingRightNow = CSPlayerLoading.IsPlaying == isPlaying |         val isPlayingRightNow = CSPlayerLoading.IsPlaying == isPlaying | ||||||
|         val isPausedRightNow = CSPlayerLoading.IsPaused == isPlaying |         val isPausedRightNow = CSPlayerLoading.IsPaused == isPlaying | ||||||
|  |  | ||||||
|  | @ -56,6 +56,7 @@ import com.lagradost.cloudstream3.TvType | ||||||
| import com.lagradost.cloudstream3.USER_AGENT | import com.lagradost.cloudstream3.USER_AGENT | ||||||
| import com.lagradost.cloudstream3.app | import com.lagradost.cloudstream3.app | ||||||
| import com.lagradost.cloudstream3.mvvm.debugAssert | import com.lagradost.cloudstream3.mvvm.debugAssert | ||||||
|  | import com.lagradost.cloudstream3.mvvm.launchSafe | ||||||
| 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.ui.subtitles.SaveCaptionStyle | import com.lagradost.cloudstream3.ui.subtitles.SaveCaptionStyle | ||||||
|  | @ -67,10 +68,15 @@ import com.lagradost.cloudstream3.utils.ExtractorLinkPlayList | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorLinkType | import com.lagradost.cloudstream3.utils.ExtractorLinkType | ||||||
| import com.lagradost.cloudstream3.utils.ExtractorUri | import com.lagradost.cloudstream3.utils.ExtractorUri | ||||||
| import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage | import com.lagradost.cloudstream3.utils.SubtitleHelper.fromTwoLettersToLanguage | ||||||
|  | import com.lagradost.fetchbutton.aria2c.Aria2Args | ||||||
| import com.lagradost.fetchbutton.aria2c.Aria2Settings | import com.lagradost.fetchbutton.aria2c.Aria2Settings | ||||||
| import com.lagradost.fetchbutton.aria2c.Aria2Starter | import com.lagradost.fetchbutton.aria2c.Aria2Starter | ||||||
|  | import com.lagradost.fetchbutton.aria2c.BtPieceSelector | ||||||
| import com.lagradost.fetchbutton.aria2c.DownloadListener | import com.lagradost.fetchbutton.aria2c.DownloadListener | ||||||
| import com.lagradost.fetchbutton.aria2c.DownloadStatusTell | import com.lagradost.fetchbutton.aria2c.DownloadStatusTell | ||||||
|  | import com.lagradost.fetchbutton.aria2c.FileAllocationType | ||||||
|  | import com.lagradost.fetchbutton.aria2c.FollowMetaLinkType | ||||||
|  | import com.lagradost.fetchbutton.aria2c.UriRequest | ||||||
| import com.lagradost.fetchbutton.aria2c.newUriRequest | import com.lagradost.fetchbutton.aria2c.newUriRequest | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.Dispatchers | import kotlinx.coroutines.Dispatchers | ||||||
|  | @ -119,6 +125,9 @@ class CS3IPlayer : IPlayer { | ||||||
|     private var lastMuteVolume: Float = 1.0f |     private var lastMuteVolume: Float = 1.0f | ||||||
| 
 | 
 | ||||||
|     private var currentLink: ExtractorLink? = null |     private var currentLink: ExtractorLink? = null | ||||||
|  | 
 | ||||||
|  |     private var currentAria2cRequestLink: ExtractorLink? = null | ||||||
|  |     private var currentAria2cRequestId: Long? = null | ||||||
|     private var currentDownloadedFile: ExtractorUri? = null |     private var currentDownloadedFile: ExtractorUri? = null | ||||||
|     private var hasUsedFirstRender = false |     private var hasUsedFirstRender = false | ||||||
| 
 | 
 | ||||||
|  | @ -354,6 +363,8 @@ class CS3IPlayer : IPlayer { | ||||||
|                     ?: throw Exception("Not downloaded enough") |                     ?: throw Exception("Not downloaded enough") | ||||||
|                 activity.runOnUiThread { |                 activity.runOnUiThread { | ||||||
|                     //Log.i(TAG, "downloaded data: $metadata") |                     //Log.i(TAG, "downloaded data: $metadata") | ||||||
|  |                     exoPlayer?.release() | ||||||
|  |                     exoPlayer = null | ||||||
|                     loadOfflinePlayer( |                     loadOfflinePlayer( | ||||||
|                         activity, |                         activity, | ||||||
|                         ExtractorUri( |                         ExtractorUri( | ||||||
|  | @ -400,13 +411,64 @@ class CS3IPlayer : IPlayer { | ||||||
|     private suspend fun playAria2c(activity: Activity, link: ExtractorLink) { |     private suspend fun playAria2c(activity: Activity, link: ExtractorLink) { | ||||||
|         // ephemeral id based on url to make it unique |         // ephemeral id based on url to make it unique | ||||||
|         val requestId = link.url.hashCode().toLong() |         val requestId = link.url.hashCode().toLong() | ||||||
|  |         currentAria2cRequestId = requestId | ||||||
|  |         currentAria2cRequestLink = link | ||||||
| 
 | 
 | ||||||
|         val uriReq = newUriRequest( |         val uriReq = UriRequest( | ||||||
|             id = requestId, |             id = requestId, | ||||||
|             uri = link.url, |             uris = listOf(link.url), | ||||||
|             fileName = null, |             args = Aria2Args( | ||||||
|             seed = false, |                 headers = link.headers, | ||||||
|             stream = true, |                 referer = link.referer, | ||||||
|  |                 /** torrent specifics to make it possible to stream */ | ||||||
|  |                 seedRatio = 0.0f, | ||||||
|  |                 seedTimeMin = 0.0f, | ||||||
|  |                 btPieceSelector = BtPieceSelector.Inorder, | ||||||
|  |                 followTorrent = FollowMetaLinkType.Mem, | ||||||
|  |                 fileAllocation = FileAllocationType.None, | ||||||
|  |                 btPrioritizePiece = "head=30M,tail=30M", | ||||||
|  |                 /** Best trackers to make it faster */ | ||||||
|  |                 btTracker = listOf( | ||||||
|  |                     "udp://tracker.opentrackr.org:1337/announce", | ||||||
|  |                     "https://tracker2.ctix.cn/announce", | ||||||
|  |                     "https://tracker1.520.jp:443/announce", | ||||||
|  |                     "udp://opentracker.i2p.rocks:6969/announce", | ||||||
|  |                     "udp://open.tracker.cl:1337/announce", | ||||||
|  |                     "udp://open.demonii.com:1337/announce", | ||||||
|  |                     "http://tracker.openbittorrent.com:80/announce", | ||||||
|  |                     "udp://tracker.openbittorrent.com:6969/announce", | ||||||
|  |                     "udp://open.stealth.si:80/announce", | ||||||
|  |                     "udp://exodus.desync.com:6969/announce", | ||||||
|  |                     "udp://tracker-udp.gbitt.info:80/announce", | ||||||
|  |                     "udp://explodie.org:6969/announce", | ||||||
|  |                     "https://tracker.gbitt.info:443/announce", | ||||||
|  |                     "http://tracker.gbitt.info:80/announce", | ||||||
|  |                     "udp://uploads.gamecoast.net:6969/announce", | ||||||
|  |                     "udp://tracker1.bt.moack.co.kr:80/announce", | ||||||
|  |                     "udp://tracker.tiny-vps.com:6969/announce", | ||||||
|  |                     "udp://tracker.theoks.net:6969/announce", | ||||||
|  |                     "udp://tracker.dump.cl:6969/announce", | ||||||
|  |                     "udp://tracker.bittor.pw:1337/announce", | ||||||
|  |                     "https://tracker1.520.jp:443/announce", | ||||||
|  |                     "udp://opentracker.i2p.rocks:6969/announce", | ||||||
|  |                     "udp://open.tracker.cl:1337/announce", | ||||||
|  |                     "udp://open.demonii.com:1337/announce", | ||||||
|  |                     "http://tracker.openbittorrent.com:80/announce", | ||||||
|  |                     "udp://tracker.openbittorrent.com:6969/announce", | ||||||
|  |                     "udp://open.stealth.si:80/announce", | ||||||
|  |                     "udp://exodus.desync.com:6969/announce", | ||||||
|  |                     "udp://tracker-udp.gbitt.info:80/announce", | ||||||
|  |                     "udp://explodie.org:6969/announce", | ||||||
|  |                     "https://tracker.gbitt.info:443/announce", | ||||||
|  |                     "http://tracker.gbitt.info:80/announce", | ||||||
|  |                     "udp://uploads.gamecoast.net:6969/announce", | ||||||
|  |                     "udp://tracker1.bt.moack.co.kr:80/announce", | ||||||
|  |                     "udp://tracker.tiny-vps.com:6969/announce", | ||||||
|  |                     "udp://tracker.theoks.net:6969/announce", | ||||||
|  |                     "udp://tracker.dump.cl:6969/announce", | ||||||
|  |                     "udp://tracker.bittor.pw:1337/announce" | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|         ) |         ) | ||||||
| 
 | 
 | ||||||
|         val metadata = |         val metadata = | ||||||
|  | @ -421,6 +483,7 @@ class CS3IPlayer : IPlayer { | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         try { |         try { | ||||||
|  |             saveData() | ||||||
|             awaitAria2c(activity, link, requestId) |             awaitAria2c(activity, link, requestId) | ||||||
|         } catch (t: Throwable) { |         } catch (t: Throwable) { | ||||||
|             // if we detect any download error then we delete it as we don't want any useless background tasks |             // if we detect any download error then we delete it as we don't want any useless background tasks | ||||||
|  | @ -500,6 +563,7 @@ class CS3IPlayer : IPlayer { | ||||||
|         if (link != null) { |         if (link != null) { | ||||||
|             loadOnlinePlayer(context, link) |             loadOnlinePlayer(context, link) | ||||||
|         } else if (data != null) { |         } else if (data != null) { | ||||||
|  |             currentAria2cRequestId = null | ||||||
|             loadOfflinePlayer(context, data) |             loadOfflinePlayer(context, data) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | @ -1320,10 +1384,64 @@ class CS3IPlayer : IPlayer { | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 override fun onPlayerError(error: PlaybackException) { |                 override fun onPlayerError(error: PlaybackException) { | ||||||
|  |                     val aria2cRequestId = currentAria2cRequestId | ||||||
|  |                     val loadedLink = currentAria2cRequestLink | ||||||
|  |                     when { | ||||||
|  |                         // if we are loading an torrent, then we will get these errors, in that case | ||||||
|  |                         // we just treat it as buffering | ||||||
|  |                         aria2cRequestId != null && loadedLink != null && | ||||||
|  |                                 (error.errorCode == PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE | ||||||
|  |                                         || error.errorCode == PlaybackException.ERROR_CODE_PARSING_MANIFEST_MALFORMED | ||||||
|  |                                         || error.errorCode == PlaybackException.ERROR_CODE_PARSING_CONTAINER_MALFORMED | ||||||
|  |                                         || error.errorCode == PlaybackException.ERROR_CODE_PARSING_CONTAINER_UNSUPPORTED | ||||||
|  |                                         ) -> { | ||||||
|  | 
 | ||||||
|  |                             val gid = DownloadListener.sessionIdToGid[aria2cRequestId] | ||||||
|  |                             Log.i(TAG, "Aria2 error $error error ${error.errorCode}") | ||||||
|  |                             if(gid == null) { | ||||||
|  |                                 event(ErrorEvent(error)) | ||||||
|  |                                 super.onPlayerError(error) | ||||||
|  |                                 return | ||||||
|  |                             } | ||||||
|  |                             event( | ||||||
|  |                                 StatusEvent( | ||||||
|  |                                     wasPlaying = CSPlayerLoading.IsPlaying, | ||||||
|  |                                     isPlaying = CSPlayerLoading.IsBuffering | ||||||
|  |                                 ) | ||||||
|  |                             ) | ||||||
|  |                             CoroutineScope(Dispatchers.IO).launchSafe { | ||||||
|  |                                 for (i in 0..5) { | ||||||
|  |                                     val metadata = DownloadListener.getInfo(gid) | ||||||
|  |                                     event( | ||||||
|  |                                         DownloadEvent( | ||||||
|  |                                             downloadedBytes = metadata.downloadedLength, | ||||||
|  |                                             downloadSpeed = metadata.downloadSpeed, | ||||||
|  |                                             totalBytes = metadata.totalLength, | ||||||
|  |                                             connections = metadata.items.sumOf { it.connections } | ||||||
|  |                                         ) | ||||||
|  |                                     ) | ||||||
|  | 
 | ||||||
|  |                                     delay(1000) | ||||||
|  |                                 } | ||||||
|  | 
 | ||||||
|  |                                // CommonActivity.activity?.runOnUiThread { | ||||||
|  |                               //      exoPlayer?.prepare() | ||||||
|  |                                // } | ||||||
|  | 
 | ||||||
|  |                                 // shitty solution to release it every time, however we will get timeout otherwise | ||||||
|  |                                 CommonActivity.activity?.let { act -> | ||||||
|  |                                     try { | ||||||
|  |                                         awaitAria2c(act, loadedLink, aria2cRequestId) | ||||||
|  |                                     }  catch (t : Throwable) { | ||||||
|  |                                         event(ErrorEvent(t)) | ||||||
|  |                                     } | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|                         // If the Network fails then ignore the exception if the duration is set. |                         // If the Network fails then ignore the exception if the duration is set. | ||||||
|                         // This is to switch mirrors automatically if the stream has not been fetched, but |                         // This is to switch mirrors automatically if the stream has not been fetched, but | ||||||
|                         // allow playing the buffer without internet as then the duration is fetched. |                         // allow playing the buffer without internet as then the duration is fetched. | ||||||
|                     when { |  | ||||||
|                         error.errorCode == PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED |                         error.errorCode == PlaybackException.ERROR_CODE_IO_NETWORK_CONNECTION_FAILED | ||||||
|                                 && exoPlayer?.duration != TIME_UNSET -> { |                                 && exoPlayer?.duration != TIME_UNSET -> { | ||||||
|                             exoPlayer?.prepare() |                             exoPlayer?.prepare() | ||||||
|  | @ -1554,6 +1672,7 @@ class CS3IPlayer : IPlayer { | ||||||
|         Log.i(TAG, "loadOnlinePlayer $link") |         Log.i(TAG, "loadOnlinePlayer $link") | ||||||
|         try { |         try { | ||||||
|             currentLink = link |             currentLink = link | ||||||
|  |             currentAria2cRequestId = null | ||||||
| 
 | 
 | ||||||
|             if (ignoreSSL) { |             if (ignoreSSL) { | ||||||
|                 // Disables ssl check |                 // Disables ssl check | ||||||
|  |  | ||||||
|  | @ -109,6 +109,14 @@ class GeneratorPlayer : FullScreenPlayer() { | ||||||
|         showDownloadProgress(event) |         showDownloadProgress(event) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /*override fun updateIsPlaying(wasPlaying: CSPlayerLoading, isPlaying: CSPlayerLoading) { | ||||||
|  |         super.updateIsPlaying(wasPlaying, isPlaying) | ||||||
|  |         if(isPlaying == CSPlayerLoading.IsPlaying) | ||||||
|  |         activity?.runOnUiThread { | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     }*/ | ||||||
|  | 
 | ||||||
|     private fun showDownloadProgress(event: DownloadEvent?) { |     private fun showDownloadProgress(event: DownloadEvent?) { | ||||||
|         activity?.runOnUiThread { |         activity?.runOnUiThread { | ||||||
|             if(event == null) { |             if(event == null) { | ||||||
|  |  | ||||||
|  | @ -30,19 +30,19 @@ | ||||||
|         app:show_timeout="0" /> |         app:show_timeout="0" /> | ||||||
| 
 | 
 | ||||||
|     <FrameLayout |     <FrameLayout | ||||||
|         android:layout_width="match_parent" |  | ||||||
|         android:layout_height="match_parent" |  | ||||||
|         android:background="@android:color/black" |         android:background="@android:color/black" | ||||||
|         android:backgroundTint="@android:color/black"> |         android:backgroundTint="@android:color/black" | ||||||
|  |         android:id="@+id/download_header" | ||||||
|  |         android:visibility="gone" | ||||||
|  |         tools:visibility="visible" | ||||||
|  |         android:layout_width="match_parent" | ||||||
|  |         android:layout_height="match_parent"> | ||||||
| 
 | 
 | ||||||
|         <LinearLayout |         <LinearLayout | ||||||
|             android:id="@+id/download_header" |  | ||||||
|             android:layout_width="match_parent" |             android:layout_width="match_parent" | ||||||
|             android:layout_height="match_parent" |             android:layout_height="match_parent" | ||||||
|             android:gravity="center" |             android:gravity="center" | ||||||
|             android:orientation="vertical" |             android:orientation="vertical"> | ||||||
|             android:visibility="gone" |  | ||||||
|             tools:visibility="visible"> |  | ||||||
| 
 | 
 | ||||||
|             <TextView |             <TextView | ||||||
|                 android:id="@+id/downloaded_progress_text" |                 android:id="@+id/downloaded_progress_text" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue