diff --git a/build.gradle b/build.gradle index f5366a4..b6f76eb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.3.72' repositories { mavenCentral() google() @@ -8,8 +9,10 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.android.tools.build:gradle:3.6.3' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + classpath 'de.undercouch:gradle-download-task:4.0.4' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle.properties b/gradle.properties index 1d3591c..d72ec75 100644 --- a/gradle.properties +++ b/gradle.properties @@ -15,4 +15,8 @@ # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects -# org.gradle.parallel=true \ No newline at end of file +# org.gradle.parallel=true + +# Enable AndroidX in this project +android.enableJetifier=true +android.useAndroidX=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 81b0639..6f3eac4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Dec 23 18:23:30 CET 2018 +#Sat Apr 18 14:47:51 EDT 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip diff --git a/library/build.gradle b/library/build.gradle index fdb8cf8..7d1858b 100644 --- a/library/build.gradle +++ b/library/build.gradle @@ -16,16 +16,16 @@ apply plugin: 'com.android.library' apply plugin: 'com.github.dcendents.android-maven' +apply plugin: 'de.undercouch.download' group='com.github.TorrentStream' android { - compileSdkVersion 28 - buildToolsVersion "28.0.3" + compileSdkVersion 29 defaultConfig { minSdkVersion 15 - targetSdkVersion 28 + targetSdkVersion 29 } buildTypes { @@ -41,14 +41,32 @@ android { } ext { - libtorrentVersion = '1.2.1.0' + libtorrentVersion = '1.2.5.0' +} + +// Custom task which downloads the appropriate version of JAR files for jlibtorrent +task downloadDependencies(type: Download) { + def baseUrl = "https://github.com/frostwire/frostwire-jlibtorrent" + + "/releases/download/release%2F$libtorrentVersion" + + def platforms = ['arm', 'arm64', 'x86', 'x86_64'] + def urls = platforms.collect { "$baseUrl/jlibtorrent-android-$it-${libtorrentVersion}.jar" } + urls.add("$baseUrl/jlibtorrent-${libtorrentVersion}.jar") + + src urls + dest 'libs' + overwrite false +} + +// Add our custom task as a dependency to the build +// You may need to run gradle sync for IDE warnings to disappear +preBuild.dependsOn(downloadDependencies) + +// Add deletion of libs folder to clean task +clean { + delete 'libs' } dependencies { api fileTree(dir: 'libs', include: ['*.jar']) - api "com.frostwire:jlibtorrent:$libtorrentVersion" - api "com.frostwire:jlibtorrent-android-arm:$libtorrentVersion" - api "com.frostwire:jlibtorrent-android-arm64:$libtorrentVersion" - api "com.frostwire:jlibtorrent-android-x86:$libtorrentVersion" - api "com.frostwire:jlibtorrent-android-x86_64:$libtorrentVersion" } diff --git a/sample/build.gradle b/sample/build.gradle index 95021e7..656cd12 100644 --- a/sample/build.gradle +++ b/sample/build.gradle @@ -18,15 +18,16 @@ */ apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { - compileSdkVersion 28 - buildToolsVersion "28.0.3" + compileSdkVersion 29 defaultConfig { applicationId "com.github.se_bastiaan.torrentstreamer.sample" minSdkVersion 15 - targetSdkVersion 28 + targetSdkVersion 29 versionCode 1 versionName "1.0" } @@ -42,7 +43,11 @@ android { } dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - implementation 'com.android.support:appcompat-v7:28.0.0' implementation project(':library') + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} +repositories { + mavenCentral() } diff --git a/sample/src/main/AndroidManifest.xml b/sample/src/main/AndroidManifest.xml index 2d0da63..472417e 100644 --- a/sample/src/main/AndroidManifest.xml +++ b/sample/src/main/AndroidManifest.xml @@ -20,7 +20,6 @@ - + + + + + + + diff --git a/sample/src/main/java/com/github/se_bastiaan/torrentstreamer/sample/MainActivity.java b/sample/src/main/java/com/github/se_bastiaan/torrentstreamer/sample/MainActivity.java deleted file mode 100644 index 4bfe5cb..0000000 --- a/sample/src/main/java/com/github/se_bastiaan/torrentstreamer/sample/MainActivity.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * - * * This file is part of TorrentStreamer-Android. - * * - * * TorrentStreamer-Android is free software: you can redistribute it and/or modify - * * it under the terms of the GNU Lesser General Public License as published by - * * the Free Software Foundation, either version 3 of the License, or - * * (at your option) any later version. - * * - * * TorrentStreamer-Android is distributed in the hope that it will be useful, - * * but WITHOUT ANY WARRANTY; without even the implied warranty of - * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * * GNU Lesser General Public License for more details. - * * - * * You should have received a copy of the GNU Lesser General Public License - * * along with TorrentStreamer-Android. If not, see . - * - */ - -package com.github.se_bastiaan.torrentstreamer.sample; - -import android.Manifest; -import android.annotation.SuppressLint; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Environment; -import android.support.v4.app.ActivityCompat; -import android.support.v7.app.AppCompatActivity; -import android.util.Log; -import android.view.View; -import android.widget.Button; -import android.widget.ProgressBar; - -import com.github.se_bastiaan.torrentstream.StreamStatus; -import com.github.se_bastiaan.torrentstream.Torrent; -import com.github.se_bastiaan.torrentstream.TorrentOptions; -import com.github.se_bastiaan.torrentstream.TorrentStream; -import com.github.se_bastiaan.torrentstream.listeners.TorrentListener; - -import java.io.UnsupportedEncodingException; -import java.net.URLDecoder; - -@SuppressLint("SetTextI18n") -public class MainActivity extends AppCompatActivity implements TorrentListener { - - private static final String TORRENT = "Torrent"; - private Button button; - private ProgressBar progressBar; - private TorrentStream torrentStream; - - private String streamUrl = "magnet:?xt=urn:btih:88594aaacbde40ef3e2510c47374ec0aa396c08e&dn=bbb%5Fsunflower%5F1080p%5F30fps%5Fnormal.mp4&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80%2Fannounce&ws=http%3A%2F%2Fdistribution.bbb3d.renderfarming.net%2Fvideo%2Fmp4%2Fbbb%5Fsunflower%5F1080p%5F30fps%5Fnormal.mp4"; - - View.OnClickListener onClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - progressBar.setProgress(0); - if(torrentStream.isStreaming()) { - torrentStream.stopStream(); - button.setText("Start stream"); - return; - } - torrentStream.startStream(streamUrl); - button.setText("Stop stream"); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - String action = getIntent().getAction(); - Uri data = getIntent().getData(); - if (action != null && action.equals(Intent.ACTION_VIEW) && data != null) { - try { - streamUrl = URLDecoder.decode(data.toString(), "utf-8"); - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - } - - TorrentOptions torrentOptions = new TorrentOptions.Builder() - .saveLocation(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)) - .removeFilesAfterStop(true) - .build(); - - torrentStream = TorrentStream.init(torrentOptions); - torrentStream.addListener(this); - - button = findViewById(R.id.button); - button.setOnClickListener(onClickListener); - progressBar = findViewById(R.id.progress); - - progressBar.setMax(100); - } - - @Override - protected void onResume() { - super.onResume(); - - if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); - } - } - - @Override - public void onStreamPrepared(Torrent torrent) { - Log.d(TORRENT, "OnStreamPrepared"); - // If you set TorrentOptions#autoDownload(false) then this is probably the place to call - // torrent.startDownload(); - } - - @Override - public void onStreamStarted(Torrent torrent) { - Log.d(TORRENT, "onStreamStarted"); - } - - @Override - public void onStreamError(Torrent torrent, Exception e) { - Log.e(TORRENT, "onStreamError", e); - button.setText("Start stream"); - } - - @Override - public void onStreamReady(Torrent torrent) { - progressBar.setProgress(100); - Log.d(TORRENT, "onStreamReady: " + torrent.getVideoFile()); - - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(torrent.getVideoFile().toString())); - intent.setDataAndType(Uri.parse(torrent.getVideoFile().toString()), "video/mp4"); - startActivity(intent); - } - - @Override - public void onStreamProgress(Torrent torrent, StreamStatus status) { - if(status.bufferProgress <= 100 && progressBar.getProgress() < 100 && progressBar.getProgress() != status.bufferProgress) { - Log.d(TORRENT, "Progress: " + status.bufferProgress); - progressBar.setProgress(status.bufferProgress); - } - } - - @Override - public void onStreamStopped() { - Log.d(TORRENT, "onStreamStopped"); - } - -} diff --git a/sample/src/main/java/com/github/se_bastiaan/torrentstreamer/sample/MainActivity.kt b/sample/src/main/java/com/github/se_bastiaan/torrentstreamer/sample/MainActivity.kt new file mode 100644 index 0000000..4eff7b5 --- /dev/null +++ b/sample/src/main/java/com/github/se_bastiaan/torrentstreamer/sample/MainActivity.kt @@ -0,0 +1,126 @@ +/* + * + * * This file is part of TorrentStreamer-Android. + * * + * * TorrentStreamer-Android is free software: you can redistribute it and/or modify + * * it under the terms of the GNU Lesser General Public License as published by + * * the Free Software Foundation, either version 3 of the License, or + * * (at your option) any later version. + * * + * * TorrentStreamer-Android is distributed in the hope that it will be useful, + * * but WITHOUT ANY WARRANTY; without even the implied warranty of + * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * * GNU Lesser General Public License for more details. + * * + * * You should have received a copy of the GNU Lesser General Public License + * * along with TorrentStreamer-Android. If not, see . + * + */ +package com.github.se_bastiaan.torrentstreamer.sample + +import android.annotation.SuppressLint +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.util.Log +import android.view.View +import android.webkit.MimeTypeMap +import android.widget.Button +import android.widget.ProgressBar +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.FileProvider +import com.github.se_bastiaan.torrentstream.StreamStatus +import com.github.se_bastiaan.torrentstream.Torrent +import com.github.se_bastiaan.torrentstream.TorrentOptions +import com.github.se_bastiaan.torrentstream.TorrentStream +import com.github.se_bastiaan.torrentstream.listeners.TorrentListener +import java.io.UnsupportedEncodingException +import java.net.URLDecoder + +@SuppressLint("SetTextI18n") +class MainActivity : AppCompatActivity(), TorrentListener { + private lateinit var button: Button + private lateinit var progressBar: ProgressBar + private lateinit var torrentStream: TorrentStream + private var streamUrl = "magnet:?xt=urn:btih:88594aaacbde40ef3e2510c47374ec0aa396c08e&dn=bbb%5Fsunflower%5F1080p%5F30fps%5Fnormal.mp4&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80%2Fannounce&ws=http%3A%2F%2Fdistribution.bbb3d.renderfarming.net%2Fvideo%2Fmp4%2Fbbb%5Fsunflower%5F1080p%5F30fps%5Fnormal.mp4" + var onClickListener = View.OnClickListener { + progressBar.progress = 0 + if (torrentStream.isStreaming) { + torrentStream.stopStream() + button.text = "Start stream" + return@OnClickListener + } + torrentStream.startStream(streamUrl) + button.text = "Stop stream" + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + val action = intent.action + val data = intent.data + if (action != null && action == Intent.ACTION_VIEW && data != null) { + try { + streamUrl = URLDecoder.decode(data.toString(), "utf-8") + } catch (e: UnsupportedEncodingException) { + e.printStackTrace() + } + } + val torrentOptions = TorrentOptions.Builder() + .saveLocation(filesDir) + .removeFilesAfterStop(true) + .build() + torrentStream = TorrentStream.init(torrentOptions) + torrentStream.addListener(this) + button = findViewById(R.id.button) + button.setOnClickListener(onClickListener) + progressBar = findViewById(R.id.progress) + progressBar.max = 100 + } + + override fun onStreamPrepared(torrent: Torrent) { + Log.d(TORRENT, "onStreamPrepared") + // If you set TorrentOptions#autoDownload(false) then this is probably the place to call + // torrent.startDownload(); + } + + override fun onStreamStarted(torrent: Torrent) { + Log.d(TORRENT, "onStreamStarted") + } + + override fun onStreamError(torrent: Torrent, e: Exception) { + Log.e(TORRENT, "onStreamError", e) + button.text = "Start stream" + } + + override fun onStreamReady(torrent: Torrent) { + progressBar.progress = 100 + val mediaFile = torrent.videoFile + Log.d(TORRENT, "onStreamReady: $mediaFile") + + // Create a sharing intent + startActivity(Intent().apply { + action = Intent.ACTION_VIEW + type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(mediaFile.extension) + val authority = "${BuildConfig.APPLICATION_ID}.provider" + data = FileProvider.getUriForFile(this@MainActivity, authority, mediaFile) + flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or + Intent.FLAG_ACTIVITY_CLEAR_TOP + }) + } + + override fun onStreamProgress(torrent: Torrent, status: StreamStatus) { + if (status.bufferProgress <= 100 && progressBar.progress < 100 && progressBar.progress != status.bufferProgress) { + Log.d(TORRENT, "Progress: " + status.bufferProgress) + progressBar.progress = status.bufferProgress + } + } + + override fun onStreamStopped() { + Log.d(TORRENT, "onStreamStopped") + } + + companion object { + private const val TORRENT = "Torrent" + } +} \ No newline at end of file diff --git a/sample/src/main/res/xml/file_paths.xml b/sample/src/main/res/xml/file_paths.xml new file mode 100644 index 0000000..d2d19b1 --- /dev/null +++ b/sample/src/main/res/xml/file_paths.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file