mirror of
https://github.com/JohnDoee/deluge-streaming/
synced 2026-07-01 07:31:17 -07:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
86c6b0db00 | ||
|
|
73ddeb021c | ||
|
|
21f1d77568 | ||
|
|
015a7cbc7a | ||
|
|
3417b109ec | ||
|
|
3a3c90ed8b | ||
|
|
bfe0f9f49c | ||
|
|
9e38de34f2 | ||
|
|
ec02a2e61d | ||
|
|
0e63ed4ebc | ||
|
|
ba6c689d98 |
@@ -51,6 +51,13 @@ The _allow remote_ option is to allow remote add and stream of torrents.
|
||||
|
||||
# Version Info
|
||||
|
||||
## Version 0.10.2
|
||||
* Busting cache when waiting for piece
|
||||
* Math error in calculating size of readable bytes
|
||||
|
||||
## Version 0.10.1
|
||||
* Small bugfixes related to priorities, should actually make sequential download work.
|
||||
|
||||
## Version 0.10.0
|
||||
* Rewrote large parts of the code
|
||||
* Now using [thomas](https://github.com/JohnDoee/thomas) as file-reading core - this adds support for multi-rar streaming.
|
||||
|
||||
23
examples/cli-stream/README.md
Normal file
23
examples/cli-stream/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Commandline Tool to stream
|
||||
|
||||
Stream from the commandline.
|
||||
|
||||
## Requirements
|
||||
|
||||
* Python
|
||||
* deluge_client python package
|
||||
|
||||
## Installation example
|
||||
|
||||
```bash
|
||||
virtualenv cli-example
|
||||
cli-example/bin/pip install deluge_client
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Open a torrent directly in VLC on Linux or OSX.
|
||||
|
||||
```bash
|
||||
vlc `cli-example/bin/python stream-cli.py username password my_video.torrent`
|
||||
```
|
||||
28
examples/cli-stream/stream-cli.py
Normal file
28
examples/cli-stream/stream-cli.py
Normal file
@@ -0,0 +1,28 @@
|
||||
import argparse
|
||||
import urllib
|
||||
|
||||
from deluge_client import DelugeRPCClient
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Stream something.')
|
||||
parser.add_argument('username', type=str, help='Deluge username')
|
||||
parser.add_argument('password', type=str, help='Deluge password')
|
||||
parser.add_argument('path_or_url', type=str, help='Path or URL to torrent')
|
||||
|
||||
parser.add_argument('--hostname', '-o', type=str, default='localhost', help='Deluge daemon hostname or ip')
|
||||
parser.add_argument('--port', '-p', type=int, default=58846, help='Deluge daemon port')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.path_or_url.startswith('http'):
|
||||
filedata = urllib.urlopen(args.path_or_url).read()
|
||||
else:
|
||||
with open(args.path_or_url, 'rb') as f:
|
||||
filedata = f.read()
|
||||
|
||||
client = DelugeRPCClient(args.hostname, args.port, args.username, args.password)
|
||||
client.connect()
|
||||
|
||||
result = client.streaming.stream_torrent(None, None, filedata, None, None, True)
|
||||
print(result['url'])
|
||||
2
setup.py
2
setup.py
@@ -42,7 +42,7 @@ from setuptools import setup, find_packages
|
||||
__plugin_name__ = "Streaming"
|
||||
__author__ = "Anders Jensen"
|
||||
__author_email__ = "johndoee@tidalstream.org"
|
||||
__version__ = "0.10.0"
|
||||
__version__ = "0.10.2"
|
||||
__url__ = "https://github.com/JohnDoee/deluge-streaming"
|
||||
__license__ = "GPLv3"
|
||||
__description__ = "Enables streaming of files while downloading them."
|
||||
|
||||
@@ -70,6 +70,7 @@ VIDEO_STREAMABLE_EXTENSIONS = ['mkv', 'mp4', 'iso', 'ogg', 'ogm', 'm4v']
|
||||
AUDIO_STREAMABLE_EXTENSIONS = ['flac', 'mp3', 'oga']
|
||||
STREAMABLE_EXTENSIONS = set(VIDEO_STREAMABLE_EXTENSIONS + AUDIO_STREAMABLE_EXTENSIONS)
|
||||
TORRENT_CLEANUP_INTERVAL = timedelta(minutes=30)
|
||||
MAX_FILE_PRIORITY = 2
|
||||
|
||||
DEFAULT_PREFS = {
|
||||
'ip': '127.0.0.1',
|
||||
@@ -164,10 +165,12 @@ class Torrent(object):
|
||||
self.torrent.handle.piece_priority(needed_piece, 7)
|
||||
|
||||
f = self.get_file_from_offset(from_byte)
|
||||
logger.debug('Also setting file to max %r' % (f, ))
|
||||
|
||||
file_priorities = self.torrent.get_file_priorities()
|
||||
file_priorities[f['index']] = 7
|
||||
self.torrent.set_file_priorities(file_priorities)
|
||||
if file_priorities[f['index']] != MAX_FILE_PRIORITY:
|
||||
logger.debug('Also setting file to max %r' % (f, ))
|
||||
file_priorities[f['index']] = MAX_FILE_PRIORITY
|
||||
self.torrent.set_file_priorities(file_priorities)
|
||||
|
||||
for _ in range(300):
|
||||
if self.torrent.status.pieces[needed_piece]:
|
||||
@@ -179,7 +182,7 @@ class Torrent(object):
|
||||
logger.debug('Calling read again to get the real number')
|
||||
return self.can_read(from_byte)
|
||||
else:
|
||||
return ((last_available_piece - needed_piece) * self.piece_length) + rest + self.piece_length
|
||||
return ((last_available_piece - needed_piece) * self.piece_length) + self.piece_length - rest
|
||||
|
||||
def is_idle(self):
|
||||
return not self.readers and self.last_activity + TORRENT_CLEANUP_INTERVAL < datetime.now()
|
||||
@@ -239,7 +242,7 @@ class Torrent(object):
|
||||
|
||||
if f['path'] in must_whitelist:
|
||||
if f['path'] in first_files:
|
||||
file_priorities[i] = 7
|
||||
file_priorities[i] = MAX_FILE_PRIORITY
|
||||
else:
|
||||
file_priorities[i] = 1
|
||||
elif f['path'] not in cannot_blacklist:
|
||||
@@ -265,6 +268,23 @@ class Torrent(object):
|
||||
else:
|
||||
fileset_ranges[fileset_hash] = fileset['files'].index(path)
|
||||
|
||||
file_priorities = self.torrent.get_file_priorities()
|
||||
logger.debug('Fileset heads: %r' % (fileset_ranges, ))
|
||||
for fileset_hash, first_file in fileset_ranges.items():
|
||||
fileset = self.filesets[fileset_hash]
|
||||
logger.debug('From index %s' % (first_file, ))
|
||||
file_mapping = {f['path']: f['index'] for f in status['files']}
|
||||
for i, f in enumerate(fileset['files']):
|
||||
index = file_mapping[f]
|
||||
if i < first_file:
|
||||
file_priorities[index] = 0
|
||||
elif i == first_file:
|
||||
file_priorities[index] = MAX_FILE_PRIORITY
|
||||
else:
|
||||
file_priorities[index] = 1
|
||||
|
||||
self.torrent.set_file_priorities(file_priorities)
|
||||
|
||||
currently_downloading = self.get_currently_downloading()
|
||||
logger.debug('File heads: %r' % (file_ranges, ))
|
||||
for f, progress in zip(status['files'], status['file_progress']):
|
||||
@@ -296,23 +316,6 @@ class Torrent(object):
|
||||
else:
|
||||
self.torrent.handle.piece_priority(piece, 1)
|
||||
|
||||
file_priorities = self.torrent.get_file_priorities()
|
||||
logger.debug('Fileset heads: %r' % (fileset_ranges, ))
|
||||
for fileset_hash, first_file in fileset_ranges.items():
|
||||
fileset = self.filesets[fileset_hash]
|
||||
logger.debug('From index %s' % (first_file, ))
|
||||
file_mapping = {f['path']: f['index'] for f in status['files']}
|
||||
for i, f in enumerate(fileset['files']):
|
||||
index = file_mapping[f]
|
||||
if i < first_file:
|
||||
file_priorities[index] = 0
|
||||
elif i == first_file:
|
||||
file_priorities[index] = 7
|
||||
else:
|
||||
file_priorities[index] = 1
|
||||
|
||||
self.torrent.set_file_priorities(file_priorities)
|
||||
|
||||
def get_currently_downloading(self):
|
||||
currently_downloading = set()
|
||||
for peer in self.torrent.handle.get_peer_info():
|
||||
@@ -388,8 +391,7 @@ class TorrentHandler(object):
|
||||
|
||||
def get_filesystem(self, infohash):
|
||||
torrent = get_torrent(infohash)
|
||||
status = torrent.get_status(['piece_length', 'files', 'file_progress', 'save_path'])
|
||||
self.piece_length = status['piece_length']
|
||||
status = torrent.get_status(['files', 'file_progress', 'save_path'])
|
||||
save_path = status['save_path']
|
||||
|
||||
found_rar = False
|
||||
@@ -453,9 +455,16 @@ class TorrentHandler(object):
|
||||
@defer.inlineCallbacks
|
||||
def stream(self, infohash, path, wait_for_end_pieces=False):
|
||||
logger.debug('Trying to get path:%s from infohash:%s' % (path, infohash))
|
||||
local_torrent = self.get_torrent(infohash)
|
||||
torrent = get_torrent(infohash)
|
||||
|
||||
for _ in range(10):
|
||||
status = torrent.get_status(['piece_length'])
|
||||
if status['piece_length'] > 0:
|
||||
break
|
||||
yield sleep(0.2)
|
||||
|
||||
local_torrent = self.get_torrent(infohash)
|
||||
|
||||
filesystem = self.get_filesystem(infohash)
|
||||
if path:
|
||||
stream_item = filesystem.get_item_from_path(path)
|
||||
|
||||
@@ -50,6 +50,9 @@ class DelugeTorrentInput(InputBase.find_plugin('file')):
|
||||
if self.can_read_to <= tell or self.can_read_to is None:
|
||||
self.can_read_to = self.torrent.can_read(self.offset + tell) + tell
|
||||
|
||||
if self._open_file:
|
||||
self._open_file.seek(tell)
|
||||
|
||||
real_num = min(num, self.can_read_to - tell)
|
||||
if num != real_num:
|
||||
logger.info('The real number we can read to is %s and not %s at position %s' % (real_num, num, tell))
|
||||
|
||||
Reference in New Issue
Block a user