chrippa / python-librtmp

python-librtmp is a RTMP client library. It uses the implementation provided by librtmp via cffi.
BSD 2-Clause "Simplified" License
153 stars 33 forks source link

Can't invoke create_stream once a stream has already been connected. #16

Open notnola opened 9 years ago

notnola commented 9 years ago

http://i.imgur.com/7bzPQI4.png

on this particular server invoking conn.connect() creates a stream

trying to invoke create_stream() after connection produces nothing. No outbound packets.

ghost commented 9 years ago

It doesn't really invoke createStream on the server, as it makes you think. You can see that in the result which indicates that it connected successfully.

EDIT: You should include the code, that would help resolving the issue. Also, the server you are trying to connect to is using http://rtmpd.com/

notnola commented 9 years ago

Yes, while I may have a successful connection, I am trying to connect to the 12 other possible streams that the server is broadcasting; but only after I receive an "avons" packet that includes the playpaths in its body. http://i.imgur.com/6xpbekl.png I have written code - witch I can supply if necessary. Its basic logic is after invoking the connect method - A while loop is created that loops the read_packet method, until there is no longer a connection. Once the avons packet is received it is parted out, and a for loop invokes the create_stream, method. But nothing happens. Also, not that this is related (at least I don't think so). I created my own call method, that removes the +=1 for the transaction_id, allowing the transaction_id to be set to zero on calls.

I also see in your repos that you are creating a tinychat client. you are more than welcome to fork my source https://github.com/phuein/pinychat

it is 99% complete on the functions with a few bugs that I will work out in the upcoming days. apart from the publishing a stream, and viewing of the published streams.

ghost commented 9 years ago

@notnola Let's wait for @chrippa's input on this.

(BTW, i'm not writing a client. It's a package i wrote a few months ago for bots, etc. I have an AI bot for it aswell.)

notnola commented 9 years ago

@norwack , yeah the way I wrote it; it could be easily used as a library. Actually a friend, MegaLoler wrote a bit of the source a while ago. I how ever have made many changes to it, and ported it over to use this library.

Back on topic; I am able to successfully the create_stream method if I invoke it BEFORE i invoke my "listen" method (while looping the read_packet" function. breaking that loop once the "avons" packet is received (so I have the playpaths) does not work. I don't understand enough of the python-librtmp code to figure out how to fix it. So any help from @chrippa would be appreciated. I am also using stock 2.4 build of librtmp.dll, and have tried other versions, both eariler, and coustom, and can't get it working.

chrippa commented 9 years ago

RTMP.create_stream calls RTMP_ConnectStream, which has it's own loop for processing packets. If you're processing packets before calling this it will probably not work, since it expects packets to happen in a certain order.

Edit: This might work, but I'm not sure:


from librtmp import RTMP, librtmp as librtmp_binding

rtmp = RTMP(...)

...

# Call RTMP_SendCreateStream directly
librtmp_binding.RTMP_SendCreateStream(rtmp.rtmp)
stream = rtmp.create_stream()
notnola commented 9 years ago

THANKS BUD! I won't have time tonight to work it out, but I will in the morning. I will update you if this works. I appreciate the help! Any word on official support for calling methods with the transaction_id of 0? Can you think of that creating any issues?

ghost commented 9 years ago

That works for opening a broadcast on TinyChat atleast, haven't tried actually sending FLV data yet. Recieving broadcasts should work fine aswell.

EDIT: I've tried passing FLV data to it, it works but audo/video kinda gets rushed over and not played correctly. a 10 second video turns into 2-3 seconds so to speak. @chrippa what is the preferred way to open a flv file and passing the data to the write function?

notnola commented 9 years ago

So @norwack, how were you able to set the playpath?

This code here is what I am using to invoke the methods. https://gist.github.com/notnola/c92554e3c97e49c429d3

With line 12 not commented and 13 commented, it produces this result. http://i.imgur.com/7sgFG6i.png

with line 13 commented and 14 not, it produces this result, http://i.imgur.com/dD6Wvjn.png

I'm lost in the sauce here.

edit, @norwack would you be willing to collaborate? Shoot me your email, and I will shoot you my skype. or email me here - I don't want to post it publicly. a4t8y@notsharingmy.info any help would be appreciated

edit2 @norwack I have some interesting code for generating a valid cauth token i'd love to share! ;)

ghost commented 9 years ago

@notnola I did something like this and i was able to playback audio and video without problems with vlc:

rtmp.set_option(key="playpath", value='8921')
rtmp.set_option(key="live", value='True')
librtmp_binding.RTMP_SendCreateStream(rtmp)
stream = rtmp.create_stream()
cam_file = open("cam.flv", "a+b")
while True:
    data = stream.read(1024)
    cam_file.write(data)
cam_file.close()

EDIT: I didn't write anything to break out of the loop if the stream is empty/finished, so .close() is not being called, however it still worked properly.

@notnola I would collaborate, however i don't think i'll have the time because i'm working on another project at the moment and i'm moving in ~1 month, etc.

phuein commented 9 years ago

@norwack I've been trying this same thing. Your example is impossible, however: rtmp.set_option implies the RTMP connection object, while RTMP_SendCreateStream(rtmp) requires a pointer: "TypeError: initializer for ctype 'RTMP *' must be a cdata pointer, not RTMP"

You can't be using the same object for both calls. Have you actually tried this code? Please share your code that did work.

I am unable to start a webcam stream download with librtmp, for no apparent reason. I have noticed that, using packets manually, I would send a "play()" packet on streamID 1, but this library doesn't let me choose which streamID I want to use. :S

Suggestions? @chrippa

ghost commented 9 years ago

@phuein Actually the code I previously posted worked, I don't know if an update to the librtmp bindings have changed or not as I haven't done anything TinyChat related in many months.

TechWhizZ199 commented 8 years ago

This is an interesting conversation guys. Though one question, this must be possible through rtmp_protocol without librtmp right? I'll give it a try, I know James has already done it, but it would be interesting to see.