[SOLVED] Python: Downloading file blocks video addons
#1
I developed the following code to Download a file from contextmenu:
Code:
progress_bar = xbmcgui.DialogProgressBG()
progress_bar.create('Download', title)

def reporthook(block_number, block_size, total_size):
    if 0 == block_number & 511:
         percent = (block_number * block_size * 100) / total_size
         progress_bar.update(percent)

urllib.urlretrieve(video_url, filename, reporthook)
progress_bar.close()

When I start downloading I cannot control my addons anymore (e.g. browsing folder of an addon).
Is it possible to have this function running and continue browsing my addons at the same time?

Edit:
If I implement the code in an addon which uses xbmcswift2 it works, but I don't know what they made different...
plugin.video.arteplussept is an example addon where it works if you edit def download_file(vid)
Reply
#2
I solved this problem using xbmc.executebuiltin(r'xbmc.RunScript(path,base64encodedArgs)' where path refers to a file download.py
which decodes the base64 string and in the file download.py the progress_bar is created.
Reply
#3
(2017-01-30, 13:00)tim619 Wrote: I solved this problem using xbmc.executebuiltin(r'xbmc.RunScript(path,base64encodedArgs)' where path refers to a file download.py
which decodes the base64 string and in the file download.py the progress_bar is created.

That sounds like a decent way to handle it. The only other way I know to deal with that is have the download and progress bar done in a separate thread. I do that for SpeedFanInfoDisplay, but it took me awhile to get my head around how threads work in python. It mostly gave me a headache, so if the excutebuiltin works, it might be worth just keeping it.
Reply
#4
I now tested the solution and it works very good even for multiple downloads at same time.
Also the performance is good.

the file download.py looks like:

Code:
import xbmcgui
import urllib
import sys

arg = sys.argv[1]
title, filename, video_url = arg.decode('base64').split('|')
progress_bar = xbmcgui.DialogProgressBG()
progress_bar.create('Downloading video', title.decode('utf-8'))


def reporthook(block_number, block_size, total_size):
    if 0 == block_number & 511:
        percent = (block_number * block_size * 100) / total_size
        progress_bar.update(percent)


urllib.urlretrieve(video_url.decode('utf-8'), filename.decode('utf-8'), reporthook)
progress_bar.close()

You can just link the contextmenu entry 'Download' to a function as normal (like you do for 'play') and from there load:
Code:
arg = '%s|%s|%s' % (title, filename, video_url)
path = os.path.join(xbmc.translatePath('special://home'), 'addons', 'plugin.video.video_id', 'resources',
                            'lib', 'download.py')
xbmc.executebuiltin(r'xbmc.RunScript(%s,%s)' % (path, arg.encode('utf-8').encode(
            'base64').strip()))

This will start a new process (from the taskmanager it seems a new thread is started because no new process is shown) which allows non-blocking.

Image
Reply
#5
(2017-02-12, 14:06)tim619 Wrote: I now tested the solution and it works very good even for multiple downloads at same time.
Also the performance is good.

the file download.py looks like:
Code:
import xbmcgui
import urllib
import sys

arg = sys.argv[1]
title, filename, video_url = arg.decode('base64').split('|')
progress_bar = xbmcgui.DialogProgressBG()
progress_bar.create('Downloading video', title.decode('utf-8'))


def reporthook(block_number, block_size, total_size):
if 0 == block_number & 511:
percent = (block_number * block_size * 100) / total_size
progress_bar.update(percent)


urllib.urlretrieve(video_url.decode('utf-8'), filename.decode('utf-8'), reporthook)
progress_bar.close()

You can just link the contextmenu entry 'Download' to a function as normal (like you do for 'play') and from there load:
Code:
arg = '%s|%s|%s' % (title, filename, video_url)
path = os.path.join(xbmc.translatePath('special://home'), 'addons', 'plugin.video.video_id', 'resources',
'lib', 'download.py')
xbmc.executebuiltin(r'xbmc.RunScript(%s,%s)' % (path, arg.encode('utf-8').encode(
'base64').strip()))

This will start a new process (from the taskmanager it seems a new thread is started because no new process is shown) which allows non-blocking.

Image

Perfect solution for me. I am starting use this in my addon. Thanks
Reply

Logout Mark Read Team Forum Stats Members Help
[SOLVED] Python: Downloading file blocks video addons0