Stream while downloading
AlenToma opened this issue · 4 comments
Thanx for sharing this library with us man.
I did create a react-native plugin for this. And I am using these version of the library.
implementation "com.github.TorrentStream:TorrentStream-Android:2.8.0"
implementation "com.github.TorrentStream:TorrentStreamServer-Android:1.0.6"
The problem is that onServerReady
gets trigered only when the whole torrent progress
is 100%
the buffer only gets 100% when the progress is 100%.
What am I doing wrong here ?
This issue has nothing with react-native But I am going to post the module I created below.
If you could have a look an see if I did something wrong. will be really helpfull
Here is the Module I created.
package com.ghondar.torrentstreamer;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Arguments;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import java.util.Map;
import java.util.HashMap;
import com.frostwire.jlibtorrent.FileStorage;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.modules.core.DeviceEventManagerModule;
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 com.github.se_bastiaan.torrentstreamserver.TorrentServerListener;
import com.github.se_bastiaan.torrentstreamserver.TorrentStreamNotInitializedException;
import com.github.se_bastiaan.torrentstreamserver.TorrentStreamServer;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URLDecoder;
import java.net.UnknownHostException;
public class TorrentStreamServerModule extends ReactContextBaseJavaModule implements TorrentServerListener {
@Override
public String getName() {
return "TorrentStreamServer";
}
private final ReactApplicationContext reactContext;
private TorrentStreamServer torrentStreamServer = null;
private String ipAddress = "127.0.0.1";
private Torrent _torrent;
private String magnetUrl;
private String url;
private int index = -1;
private boolean firstRun = false;
private String _location;
public TorrentStreamServerModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
private void setup(String location, Boolean removeAfterStop) {
if (location == null)
location = "" + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
this._location = location;
if (this.torrentStreamServer == null) {
TorrentOptions torrentOptions = new TorrentOptions.Builder()
.saveLocation(location)
.removeFilesAfterStop(removeAfterStop)
.build();
torrentStreamServer = TorrentStreamServer.getInstance();
torrentStreamServer.setTorrentOptions(torrentOptions);
torrentStreamServer.setServerHost(ipAddress);
torrentStreamServer.setServerPort(8080);
torrentStreamServer.startTorrentStream();
torrentStreamServer.addListener(this);
}
}
public void sendEvent(String eventName, @Nullable WritableMap params) {
this.reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
}
@ReactMethod
public void start(String magnetUrl, String location, Boolean removeAfterStop) {
this.magnetUrl = magnetUrl;
this.setup(location, removeAfterStop);
try {
this.torrentStreamServer.startStream(magnetUrl);
} catch (IOException | TorrentStreamNotInitializedException e) {
WritableMap info = Arguments.createMap();
info.putString("msg", e.toString());
this.sendEvent("error", info);
}
}
@ReactMethod
public void stop() {
if (this.torrentStreamServer != null)
this.torrentStreamServer.stopTorrentStream();
}
private WritableArray getFileInfos() {
FileStorage fileStorage = this._torrent.getTorrentHandle().torrentFile().files();
WritableArray infos = Arguments.createArray();
for (int i = 0; i < fileStorage.numFiles(); i++) {
WritableMap info = Arguments.createMap();
info.putString("path", this._location + "/" + fileStorage.filePath(i));
info.putString("fileName", fileStorage.fileName(i));
info.putDouble("size", fileStorage.fileSize(i));
infos.pushMap(info);
}
return infos;
}
@Override
public void onStreamPrepared(Torrent torrent) {
WritableMap params = Arguments.createMap();
if (this.index == -1) {
Long size = 0L;
FileStorage fileStorage = this._torrent.getTorrentHandle().torrentFile().files();
for (int i = 0; i < fileStorage.numFiles(); i++) {
if (fileStorage.fileSize(i) > size) {
size = fileStorage.fileSize(i);
this.index = i;
}
}
torrent.setSelectedFileIndex(this.index);
}
params.putString("magnetUrl", "" + this.magnetUrl);
params.putString("data", "OnStreamPrepared");
this.sendEvent("progress", params);
}
@Override
public void onStreamStarted(Torrent torrent) {
this._torrent = torrent;
WritableMap params = Arguments.createMap();
params.putString("magnetUrl", "" + this.magnetUrl);
if (!this.firstRun)
params.putArray("files", this.getFileInfos());
params.putString("data", "onStreamStarted");
this.firstRun = true;
this.sendEvent("progress", params);
}
@Override
public void onStreamError(Torrent torrent, Exception e) {
WritableMap params = Arguments.createMap();
params.putString("magnetUrl", "" + this.magnetUrl);
params.putString("msg", e.getMessage());
params.putString("data", "onStreamError");
this.sendEvent("error", params);
}
@Override
public void onStreamReady(Torrent torrent) {
WritableMap params = Arguments.createMap();
params.putString("magnetUrl", "" + this.magnetUrl);
params.putString("url", torrent.getVideoFile().toString());
params.putString("filename", torrent.getTorrentHandle().name());
params.putString("url", url);
params.putString("data", "onStreamReady");
this.sendEvent("ready", params);
}
@Override
public void onStreamProgress(Torrent torrent, StreamStatus status) {
WritableMap params = Arguments.createMap();
params.putString("magnetUrl", "" + this.magnetUrl);
params.putString("buffer", "" + status.bufferProgress);
params.putString("downloadSpeed", "" + status.downloadSpeed);
params.putString("progress", "" + status.progress);
params.putString("seeds", "" + status.seeds);
try {
params.putString("url", this.torrentStreamServer.getCurrentStreamUrl());
} catch (Exception e) {
}
params.putString("data", "onStreamProgress");
this.sendEvent("status", params);
}
@Override
public void onStreamStopped() {
WritableMap params = Arguments.createMap();
params.putString("magnetUrl", "" + this.magnetUrl);
params.putString("data", "OnStreamStoped");
this.sendEvent("stop", params);
}
@Override
public void onServerReady(String url) {
WritableMap params = Arguments.createMap();
this.url = url;
params.putString("url", url);
params.putString("data", "onServerReady");
this.sendEvent("serverReady", params);
}
}
The only thing I notice in your code is that you are selecting the largest file in onStreamPrepared
, which the TorrentStream library already does by default.
That onReady is not called means that the pieces that were selected as the start/end of the file were not downloaded yet.
And since you have not disabled the auto download option I think that is where your problem may be. The download already started, then you change the selected file.
Could you try using the default behaviour by not selecting a new file in onPrepared?
I have removed the selectedIndex code(that you mentioned) and the problem still accord the buffer dose not reach 100%
I have tested it with this https://yts.mx/torrent/download/32B403D8FD0571C5B5D15D6D931AE38CCCC24BAA
torrent
and when the progress
is 48 the buffer is 45. As you can see that I have to wait for the whole file to be downloaded before I can stream it.
And sadly there is also the different in speed between utorrent
and the current stream service. I would guess that it dose not use all the seeds. That is only a guess though.
Have a look below, this prove what I say
I think that this problem is related to #49 (comment)
I hope it works now, since I closed #49. If you still happen to be working on this, you're welcome to reopen this issue if it persists.