2

Possible Duplicate:
How can I run an external command asynchronously from Python?

So far my bit of code WILL download the file and then play it. What I would like to do is start downloading the file and after say 30 sec's start to watch the download.

This is the code:

urllib.urlretrieve(url2, "/hdd/movie/movie"))
sleep(30)
self.session.open(MoviePlayer, sref)

from looking about i thought this might work;

os.spawnl(os.P_NOWAIT, urllib.urlretrieve(url2, "/hdd/movie/movie"))
sleep(30)                
self.session.open(MoviePlayer, sref) 

but this does exactly the same and completes the download before playing

Community
  • 1
  • 1
  • 2
    You might want to provide a little more detail. Like the language you're using for example. – Brandon Jan 18 '13 at 22:50
  • @tcaswell I see that is a very different question. What is wanted here is a method to partially download a file, not to run it, for example, in background and wait for its completion. – mmgp Jan 19 '13 at 01:13
  • @mmgp hmm, on consideration, I think you are right (that I am wrong). – tacaswell Jan 19 '13 at 01:23
  • For those voting to close this question, be sure that you are aware that starting a new process is irrelevant here, it is merely a detail in the solution but it doesn't solve anything per se. What is required is a way to guarantee that something has been written to a file, which is not guaranteed by the use of `urlretrieve`. – mmgp Jan 19 '13 at 04:18

1 Answers1

0

If you want to start watching the movie before the download finishes, you need to use a method that partially downloads your fie and, mostly important, flushes the writes. The code used by urlretrieve writes the data in such way that it is buffered, so it is not immediately available.

Here is some basic code to perform exactly that:

import sys
import urllib2
import subprocess

url = sys.argv[1]
outname = sys.argv[2]

response = urllib2.urlopen(url)
output = open(outname, 'wb')

chunk_bytesize = 1024 * 1024

data = response.read(chunk_bytesize)
output.write(data)
output.flush()

# Now you can call your movie player.
subprocess.Popen(["open", outname])

# Read the rest of the data.
while True:
    print "Data.."
    data = response.read(chunk_bytesize)
    if not data:
        break
    output.write(data)
    output.flush()

response.close()
output.close()

In this case, the specified program is started after the first chunk is read. You could increase the size of chunk or start it after reading several chunks.

mmgp
  • 18,901
  • 3
  • 53
  • 80
  • Thankyou mmgp, this looks like it will work for me, can you just explain the syntax for opening my MoviePlayer with subprocess.Popen. if I use self.session.open(MoviePlayer, sref) and dont "read the rest of the data" then this plays the 1mb perfect,if I "read the rest of the data" then I only get audio for the 1mb but the rest of the file does then download but doesn't continue to play. I should also point out that I am running this on a Enigma2 set top box – user1991858 Jan 19 '13 at 08:11
  • @user1991858 I don't know what is `self.session` refer to, so you will need to explain that. What I think you will need to do is copy the partially downloaded file to another file and open it, then when you grab another chunk you rewrite this file again. What I'm not sure is if your player supports this, you need to know what it supports. – mmgp Jan 19 '13 at 13:15