CodenameOne WebRTC CN1LIB Serverless, Manual Signaling - webrtc

I am trying to breakdown the process of the webrtc signaling using the PeerConnectionStates Demo by copying the signaling strings manually like as in here Youtube:https://www.youtube.com/watch?v=YLPRBYTeoF4&t=1594s .
Github: https://github.com/chrisuehlinger/serverless-webrtc (from 25:00)
With success I would be able to troubleshoot any signaling problems from Pubnub, Firebase or any other signaling solution I may choose.
I have buttons Start, Call, Exchange and Hang.
The 'Exchange' Button shows an Interactive Dialog which has buttons
Copy Offer , Paste Offer, Set Offer, Copy Answer, Paste Answer, Set Answer. And also 'Copy Offer 2 from text file', and 'Copy Answer 2 from text file'.
If you click on the 1st set of the Dialog buttons in that order (excluding the last 2 file selection buttons), you complete the negotiation as in the original demo.
But I want it to be between 2 devices so I put the offer string from device A into a text file and paste into the text field of device B using Copy Offer 2 from text file, then click 'set offer' to generate an answer which I copy into a text file and send to device A using Copy Answer 2 from text file.
I was not able to place a finger on what I was missing. Any help is appreciated.
public class NewClass extends Form implements AutoCloseable {
private RTCVideoElement video1, video2;
private Button startButton = new Button("Start"),
callButton = new Button("Call"),
hangupButton = new Button("Hang up"),
sendOffer = new Button("Exchange"),
sendAnswer = new Button("Send Answer"),
setOffer = new Button("Set Offer"),
setAnswer = new Button("Set Answer"),
copyOffer = new Button("copy Offer"),
pasteOffer = new Button("paste Offer"),
copyAnswer = new Button("copy Answer"),
pasteAnswer = new Button("paste Answer"),
copyOffer2 = new Button("copy Offer 2- from text file"),
setOffer2 = new Button("set Offer 2"),
copyAnswer2 = new Button("copy Answer 2- from text file"),
setAnswer2 = new Button("set Answer 2");
private TextArea toffer1 = new TextArea("", 5, 7, TextArea.ANY),
toffer2 = new TextArea("", 5, 7, TextArea.ANY),
tAnswer1 = new TextArea("", 5, 7, TextArea.ANY),
tAnswer2 = new TextArea("", 5, 7, TextArea.ANY);
{
startButton.setEnabled(true);
callButton.setEnabled(false);
hangupButton.setEnabled(false);
startButton.addActionListener(evt->start());
callButton.addActionListener(evt->call());
hangupButton.addActionListener(evt->hangup());
sendOffer.addActionListener(evt->sendOffer());
// sendAnswer.addActionListener(evt->sendAnswer());
setOffer.addActionListener(evt->setOffer());
setAnswer.addActionListener(evt->setAnswer());
copyOffer.addActionListener(evt->{ Display.getInstance().copyToClipboard(toffer1.getText()); });
pasteOffer.addActionListener(evt->{ toffer2.setText((String)Display.getInstance().getPasteDataFromClipboard()); });
copyAnswer.addActionListener(evt->{ Display.getInstance().copyToClipboard(tAnswer1.getText()); });
pasteAnswer.addActionListener(evt->{ tAnswer2.setText((String)Display.getInstance().getPasteDataFromClipboard()); });
copyOffer2.addActionListener(evt->{
if (FileChooser.isAvailable()) {
FileChooser.showOpenDialog(".xls, .csv, text/plain", e2-> {
String file = (String)e2.getSource();
if (file == null) {
// hi.add("No file was selected");
// hi.revalidate();
} else {
String extension = null;
if (file.lastIndexOf(".") > 0) {
extension = file.substring(file.lastIndexOf(".")+1);
}
if ("txt".equals(extension)) {
FileSystemStorage fs = FileSystemStorage.getInstance();
try {
InputStream fis = fs.openInputStream(file);
// hi.addComponent(new SpanLabel(Util.readToString(fis)));
toffer1.setText(Util.readToString(fis));
} catch (Exception ex) {
Log.e(ex);
}
} else {
// hi.add("Selected file "+file);
}
}
//hi.revalidate();
});
}
});
copyAnswer2.addActionListener(evt->{
if (FileChooser.isAvailable()) {
FileChooser.showOpenDialog("text/plain", e2-> {
String file = (String)e2.getSource();
if (file == null) {
// hi.add("No file was selected");
// hi.revalidate();
} else {
String extension = null;
if (file.lastIndexOf(".") > 0) {
extension = file.substring(file.lastIndexOf(".")+1);
}
if ("txt".equals(extension)) {
FileSystemStorage fs = FileSystemStorage.getInstance();
try {
InputStream fis = fs.openInputStream(file);
// hi.addComponent(new SpanLabel(Util.readToString(fis)));
tAnswer1.setText(Util.readToString(fis));
} catch (Exception ex) {
Log.e(ex);
}
} else {
// hi.add("Selected file "+file);
}
}
//hi.revalidate();
});
}
});
}
InteractionDialog dlg = new InteractionDialog(" - - -");
{dlg.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
dlg.setScrollable(true);
dlg.setDisposeWhenPointerOutOfBounds(true);
dlg.add(" the offer - copy this offer ");dlg.add(copyOffer);dlg.add(copyOffer2);
dlg.addComponent(toffer1); dlg.add("===============================");
dlg.add(" paste offer here ");dlg.add(pasteOffer);
dlg.addComponent(toffer2);
dlg.addComponent(setOffer);
dlg.add("===============================");
dlg.add(" copy this answer ");dlg.add(copyAnswer);dlg.add(copyAnswer2);
dlg.addComponent(tAnswer1);
dlg.add("===============================");
dlg.add("paste answer here");dlg.add(pasteAnswer);
dlg.addComponent(tAnswer2);
dlg.addComponent(setAnswer);
}
private void sendOffer() {
//= call
Dimension pre = dlg.getContentPane().getPreferredSize();
dlg.show(Display.getInstance().getDisplayHeight()/16,0, Display.getInstance().getDisplayWidth()/16, 0);
} /*
private void sendAnswer() {
}*/
private Date startTime;
private MediaStream localStream;
private RTCPeerConnection pc1, pc2;
private SpanLabel pc1StateDiv = new SpanLabel();
private SpanLabel pc2StateDiv = new SpanLabel();
private SpanLabel pc1IceStateDiv = new SpanLabel();
private SpanLabel pc2IceStateDiv = new SpanLabel();
private SpanLabel pc1ConnStateDiv = new SpanLabel();
private SpanLabel pc2ConnStateDiv = new SpanLabel();
private static final RTCOfferOptions offerOptions = new RTCOfferOptions()
.offerToReceiveAudio(true)
.offerToReceiveVideo(true);
private RTC rtc;
public NewClass() {
super("Peer Connection Demo", new BorderLayout());
Container center = new Container(BoxLayout.y());
Container videoCnt = new Container(new BorderLayout());
String intro = "This sample was adapted from the \"PeerConnection: States Demo\" on the WebRTC web site.";
Button viewSource = new Button("View Source");
FontImage.setMaterialIcon(viewSource, FontImage.MATERIAL_LINK);
viewSource.addActionListener(evt->CN.execute("https://github.com/shannah/CN1WebRTC/blob/master/src/com/codename1/webrtc/demos/PeerConnectionStatesDemo.java"));
add(BorderLayout.NORTH, BoxLayout.encloseY(new SpanLabel(intro), viewSource));
//,toffer1,tAnswer1,setAnswer,toffer2,setOffer,tAnswer2
videoCnt.add(BorderLayout.SOUTH, FlowLayout.encloseCenter(startButton, callButton,sendOffer, hangupButton));
videoCnt.setPreferredH(CN.getDisplayHeight()/2);
center.add(videoCnt);
center.add("PC1 state:").
add(pc1StateDiv).
add("PC1 ICE state:").
add(pc1IceStateDiv).
add("PC1 connection state:").
add(pc1ConnStateDiv).
add("PC2 state:").
add(pc2StateDiv).
add("PC2 ICE state:").
add(pc2IceStateDiv).
add("PC2 connection state:").
add(pc2ConnStateDiv).
add(new SpanLabel("View the console to see logging. The MediaStream object localStream, and the RTCPeerConnection objects localPeerConnection and remotePeerConnection are in global scope, so you can inspect them in the console as well."));
center.setScrollableY(true);
add(BorderLayout.CENTER, center);
RTC.createRTC().onSuccess(r->{
rtc = r;
video1 = rtc.createVideo();
video1.setAutoplay(true);
video1.setMuted(true);
video1.applyStyle("position:fixed;width:50%;height:100%;top:0;left:0;bottom:0;");
video2 = rtc.createVideo();
video2.setAutoplay(true);
video2.applyStyle("position:fixed;width:50%;height:100%;top:0;right:0;bottom:0;");
rtc.append(video1);
rtc.append(video2);
video1.onloadedmetadata(evt->{
System.out.println("Local video videoWidth: "+video1.getVideoWidth()+"px, videoHeight: "+video1.getVideoHeight()+"px");
});
video2.onloadedmetadata(evt->{
System.out.println("Remote video size changed to "+video2.getVideoWidth()+"x"+video2.getVideoHeight());
if (startTime != null) {
long elapsedTime = System.currentTimeMillis() - startTime.getTime();
System.out.println("Setup time: "+elapsedTime+"ms");
startTime = null;
}
});
videoCnt.add(BorderLayout.CENTER, rtc.getVideoComponent());
revalidateWithAnimationSafety();
});
}
private void gotStream(MediaStream stream) {
Log.p("Received local stream");
video1.setSrcObject(stream);
localStream = stream;
stream.retain();
callButton.setEnabled(true);
}
private void start() {
Log.p("Requesting local stream");
startButton.setEnabled(false);
rtc.getUserMedia(new MediaStreamConstraints().audio(true).video(true)).onSuccess(stream->{
gotStream(stream);
}).onFail(t->{
Log.e((Throwable)t);
Dialog.show("Error", "getUserMedia() error: "+((Throwable)t).getMessage(), "OK", null);
});
}
private void call() {
callButton.setEnabled(false);
hangupButton.setEnabled(true);
Log.p("Starting call");
startTime = new Date();
MediaStreamTracks videoTracks = localStream.getVideoTracks();
MediaStreamTracks audioTracks = localStream.getAudioTracks();
if (videoTracks.size() > 0) {
Log.p("Using video device "+videoTracks.get(0).getLabel());
}
if (audioTracks.size() > 0) {
Log.p("Using audio device "+audioTracks.get(0).getLabel());
}
RTCConfiguration servers = new RTCConfiguration();
pc1 = rtc.newRTCPeerConnection(servers);
Log.p("Created local peer connection object pc1");
pc1StateDiv.setText(pc1.getSignalingState()+"");
pc1.onsignalingstatechange(evt->stateCallback1());
pc1IceStateDiv.setText(pc1.getIceConnectionState()+"");
pc1.oniceconnectionstatechange(evt->iceStateCallback1())
.onconnectionstatechange(evt->connStateCallback1())
.onicecandidate(e->onIceCandidate(pc1, e));
/* */
pc2 = rtc.newRTCPeerConnection(servers);
Log.p("Created remote peer connection object pc2");
pc2StateDiv.setText(pc2.getSignalingState()+"");
pc2.onsignalingstatechange(evt->stateCallback2());
pc2IceStateDiv.setText(pc2.getIceConnectionState()+"");
pc2.oniceconnectionstatechange(evt->iceStateCallback2())
.onconnectionstatechange(evt->connStateCallback2())
.onicecandidate(evt->{
onIceCandidate(pc2, evt);
});
pc2.ontrack(evt->gotRemoteStream(evt));
for (MediaStreamTrack track : localStream.getTracks()) {
pc1.addTrack(track, localStream);
}
Log.p("Adding local stream to peer connection");
/* */
pc1.createOffer(offerOptions).onSuccess(offer->{
gotDescription1(offer);
})
.onFail(e-> {
onCreateSessionDescriptionError((Throwable)e);
});
}
private void onCreateSessionDescriptionError(Throwable e) {
Log.p("Failed to create session description: "+e.getMessage(), Log.ERROR);
}
private void gotDescription1(RTCSessionDescription description) {
pc1.setLocalDescription(description);
Log.p("Offer from pc1:\n"+description.getSdp());
sendOffer(description.getSdp());
}
private void sendOffer(String jsDesc) {
toffer1.setText(jsDesc);
// getOffer(jsDesc);
}
private void setOffer() {
String desc = toffer2.getText();
if(desc.endsWith("\n")){getOffer(desc);}else{getOffer(desc+"\n");}
}
private void getOffer(String jsDesc) {
RTCSessionDescription description = rtc.createSessionDescription(RTCSessionDescription.RTCSdpType.Offer, jsDesc);
pc2.setRemoteDescription(description).onSuccess(ef->{
})
.onFail(e->onCreateSessionDescriptionError((Throwable)e)); ;
pc2.createAnswer()
.onSuccess(desc->{ sendAnswer(desc.getSdp()); } )
.onFail(e->onCreateSessionDescriptionError((Throwable)e));
}
private void sendAnswer(String jsDesc) {
tAnswer1.setText(jsDesc);
// getAnswer(jsDesc);
}
private void setAnswer() {
String desc = tAnswer2.getText();
//getAnswer(desc+"\n");
//getAnswer(desc);
if(desc.endsWith("\n")){getAnswer(desc);}else{getAnswer(desc+"\n");}
}
private void getAnswer(String jsDesc) {
RTCSessionDescription description = rtc.createSessionDescription(RTCSessionDescription.RTCSdpType.Answer, jsDesc);
gotDescription2(description);
}
private void gotDescription2(RTCSessionDescription description) {
pc2.setLocalDescription(description);
Log.p("Answer from pc2\n"+description.getSdp());
pc1.setRemoteDescription(description);
}
private void hangup() {
Log.p("Ending call");
pc1.close();
pc2.close();
pc1StateDiv.setText(pc1StateDiv.getText() + pc1.getSignalingState());
pc2StateDiv.setText(pc2StateDiv.getText() + pc2.getSignalingState());
pc1.release();
pc1 = null;
pc2.release();
pc2 = null;
hangupButton.setEnabled(false);
callButton.setEnabled(true);
}
private void gotRemoteStream(RTCTrackEvent e) {
if (video2.getSrcObject() != e.getStreams().get(0)) {
video2.setSrcObject(e.getStreams().get(0));
Log.p("Got remote stream");
}
}
private void stateCallback1() {
if (pc1 != null) {
Log.p("pc1 state change callback, state: "+pc1.getSignalingState());
pc1StateDiv.setText(pc1StateDiv.getText() + pc1.getSignalingState());
}
}
private void stateCallback2() {
if (pc2 != null) {
Log.p("pc2 state change callback, state: "+pc2.getSignalingState());
pc2StateDiv.setText(pc2StateDiv.getText() + pc2.getSignalingState());
}
}
private void iceStateCallback1() {
if (pc1 != null) {
Log.p("pc1 ICE connection state change callback, state: "+pc1.getIceConnectionState());
pc1IceStateDiv.setText(pc1IceStateDiv.getText() + pc1.getIceConnectionState());
}
}
private void iceStateCallback2() {
if (pc2 != null) {
Log.p("pc2 ICE connection state change callback, state: "+pc2.getIceConnectionState());
pc2IceStateDiv.setText(pc2IceStateDiv.getText() + pc2.getIceConnectionState());
}
}
private void connStateCallback1() {
if (pc1 != null) {
Log.p("pc1 connection state change callback, state: "+pc1.getConnectionState());
pc1ConnStateDiv.setText(pc1ConnStateDiv.getText() + pc1.getConnectionState());
}
}
private void connStateCallback2() {
if (pc2 != null) {
Log.p("pc2 connection state change callback, state: "+pc2.getConnectionState());
pc2ConnStateDiv.setText(pc2ConnStateDiv.getText() + pc2.getConnectionState());
}
}
private RTCPeerConnection getOtherPc(RTCPeerConnection pc) {
return pc == pc1 ? pc2 : pc1;
}
private String getName(RTCPeerConnection pc) {
return pc == pc1 ? "pc1" : "pc2";
}
private void onIceCandidate(RTCPeerConnection pc, RTCPeerConnectionIceEvent event) {
getOtherPc(pc).addIceCandidate(event.getCandidate())
.onSuccess(res->onAddIceCandidateSuccess(pc))
.onFail(e->{
Log.e((Throwable)e);
onAddIceCandidateError(pc, (Throwable)e);
}).onComplete(e->{
Log.p(getName(pc)+" ICE candidate:\n"+(event.getCandidate() != null ? event.getCandidate().getCandidate() : "(null"));
});
}
private void onAddIceCandidateSuccess(RTCPeerConnection pc) {
Log.p(getName(pc)+" addIceCandidate success");
}
private void onAddIceCandidateError(RTCPeerConnection pc, Throwable error) {
Log.p(getName(pc)+" failed to add ICE Candidate: "+error.getMessage(), Log.ERROR);
}
#Override
public void close() throws Exception {
if (rtc != null) {
rtc.close();
rtc = null;
}
if (pc1 != null) {
pc1.release();
pc1 = null;
}
if (pc2 != null) {
pc2.release();
pc2 = null;
}
}
}
Call is initiated from Phone - as device A to Simulator
On device A - My Phone
PC1 state:
nullHaveLocalOfferStable
PC1 ICE state:
New
PC1 connection state:
PC2 state:
nullHaveRemoteOffer
PC2 ICE state:
New
PC2 connection state:
On Device B - PC Simulator
PC1 state:
nullHaveLocalOfferStable
PC1 ICE state:
NewCheckingConnected
PC1 connection state:
Connecting
PC2 state:
nullHaveRemoteOfferStable
PC2 ICE state:
NewChecking
PC2 connection state:
Connecting
There is an error message:
java.lang.RuntimeException: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Error processing ICE candidate
But the final 3 lines on the console are
[EDT] 0:20:48,103 - pc2 addIceCandidate success
[EDT] 0:20:48,103 - pc2 ICE candidate:
candidate:1503035259 1 udp 7935 154.127.57.220 50066 typ relay raddr 129.205.113.2 rport 6591 generation 0 ufrag lXG+ network-cost 999
My Steps are:
from A
Start Button
Call Button - Creates Offer
Copy Offer from toffer1 (using Exchange Button)
Paste into toffer2
Set Offer Button
on B
6. Start Button
7. Call Button
8. Paste Offer of A into TextArea toffer1 and toffer2 (using Exchange Button)
9. Set Offer Button
10. Copy Answer from tAnswer1
11. Paste Answer into tAnswer2
on A
Paste Answer on tAnswer1 and tAnswer2
Set Answer Button
on B
14. set Answer Button

Related

youtube live broadcast lifeCycleStatus stuck on 'liveStarting'

I'm trying to figure out what i'm doing wrong when broadcast to live. I have my apk on my android phone stream to youtube. I have no problem streaming for the first time. But if I stop it for about 2 - 3 minutes, and stream again, the lifeCycleStatus of the boardcast keep stay at "liveStarting" and my video is not visible to audience. If I stop long enough, restart stream, the status will go 'live' in about 10 seconds. I have enableMonitorStream disable, and also try LiveBroadcasts.Transition, but it return error redundantTransition. But the lifeCycleStatus wouldn't turn to 'live'. I also try create a new live broadcast and live stream and change the status to 'live' manually, but both get stuck on 'liveStarting'.
public class YoutubeService {
private WeakReference<Context> context;
private static final String PREF_ACCOUNT_NAME = "youtube_account_name";
private static final String[] SCOPES = {YouTubeScopes.YOUTUBE};
private GoogleAccountCredential mCredential;
private YouTube mService;
public YoutubeService(Context context) {
this.context = new WeakReference<Context>(context);
// create account credential
mCredential = GoogleAccountCredential.usingOAuth2(
context, Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff());
mCredential.setSelectedAccountName("xxxx#gmail.com");
// create youtube builder
HttpTransport transport = AndroidHttp.newCompatibleTransport();
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
mService = new YouTube.Builder(
transport, jsonFactory, mCredential)
.setApplicationName("My App Name")
.build();
}
// AsyncTask<Void, Void, Map<String, String>>
private void getRtmpUrl() {
try {
// get livebroadcast list
YouTube.LiveBroadcasts.List liveBroadcastRequest = mService.liveBroadcasts().list("id,snippet,contentDetails,status");
liveBroadcastRequest.setBroadcastType("persistent");
liveBroadcastRequest.setMine(true);
LiveBroadcastListResponse liveBroadcastListResponse = liveBroadcastRequest.execute();
List<LiveBroadcast> liveBroadcastList = liveBroadcastListResponse.getItems();
if (liveBroadcastList != null && liveBroadcastList.size() > 0) {
LiveBroadcast liveBroadcast = liveBroadcastList.get(0);
String streamId = liveBroadcast.getContentDetails().getBoundStreamId();
// get livestream list
YouTube.LiveStreams.List livestreamRequest = mService.liveStreams().list("id,cdn");
livestreamRequest.setId(streamId);
LiveStreamListResponse liveStreamListResponse = livestreamRequest.execute();
List<LiveStream> liveStreamList = liveStreamListResponse.getItems();
if (liveStreamList != null && liveStreamList.size() > 0) {
LiveStream liveStream = liveStreamList.get(0);
String serverUrl = liveStream.getCdn().getIngestionInfo().getIngestionAddress();
String streamName = liveStream.getCdn().getIngestionInfo().getStreamName();
String rtmpUrl = serverUrl + "/" + streamName;
// use this rtmpUrl for streaming
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
// call 30 seconds after press start streaming
private void checkStatus() {
try {
// get livebroadcast list
YouTube.LiveBroadcasts.List liveBroadcastRequest = mService.liveBroadcasts().list("id,snippet,contentDetails,status");
liveBroadcastRequest.setBroadcastType("persistent");
liveBroadcastRequest.setMine(true);
LiveBroadcastListResponse liveBroadcastListResponse = liveBroadcastRequest.execute();
List<LiveBroadcast> liveBroadcastList = liveBroadcastListResponse.getItems();
if (liveBroadcastList != null && liveBroadcastList.size() > 0) {
LiveBroadcast liveBroadcast = liveBroadcastList.get(0);
// get lifeCycleStatus
String lifeCycleStatus = liveBroadcast.getStatus().getLifeCycleStatus();
String recordingStatus = liveBroadcast.getStatus().getRecordingStatus();
if (lifeCycleStatus != null && lifeCycleStatus.equalsIgnoreCase("live") && recordingStatus != null && recordingStatus.equalsIgnoreCase("recording")) {
String videoId = liveBroadcast.getId();
// the url to watch is www.youtube.com/watch?v=videoId
// video is visible to audience
} else {
// the status is stuck at 'liveStarting', video is not visible to audience
// "status":{"lifeCycleStatus":"liveStarting","privacyStatus":"public","recordingStatus":"recording"}
// check the status of livestream
String boundStreamId = liveBroadcast.getContentDetails().getBoundStreamId();
YouTube.LiveStreams.List livestreamRequest = mService.liveStreams().list("id,cdn,status");
livestreamRequest.setId(boundStreamId);
LiveStreamListResponse liveStreamListResponse = livestreamRequest.execute();
List<LiveStream> liveStreamList = liveStreamListResponse.getItems();
if (liveStreamList != null && liveStreamList.size() > 0) {
LiveStream liveStream = liveStreamList.get(0);
String streamStatus = liveStream.getStatus().getStreamStatus();
if (streamStatus.equalsIgnoreCase("active")) {
// Log.e(TAG,"need to transite to live, liveBroadcastId = " + liveBroadcast.getId());
YouTube.LiveBroadcasts.Transition liveBroadcastTransitionRequest =
mService.liveBroadcasts().transition("live", liveBroadcast.getId(), "id,status");
LiveBroadcast liveBroadcastTransitionResponse = liveBroadcastTransitionRequest.execute();
// get error here
// error 403 Forbidden
// {
// "code" : 403,
// "errors" : [ {
// "domain" : "youtube.liveBroadcast",
// "message" : "Redundant transition",
// "reason" : "redundantTransition"
// } ],
// "message" : "Redundant transition"
// }
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
// also try to create livebroadcast and live stream instead of the default one
private void createLiveBroadcast() {
try {
// step 1 create live broadcast
LiveBroadcastSnippet broadcastSnippet = new LiveBroadcastSnippet();
broadcastSnippet.setTitle("Test live broadcast title");
Date currentTime = Calendar.getInstance().getTime();
broadcastSnippet.setScheduledStartTime(new DateTime(currentTime));
LiveBroadcastStatus status = new LiveBroadcastStatus();
status.setPrivacyStatus("public");
// disable MonitorStreamInfo to change transition from ready to live
// refrence https://stackoverflow.com/questions/35003786/cannot-make-transition-of-my-youtube-broadcast-to-live-using-youtube-api
LiveBroadcastContentDetails contentDetails = new LiveBroadcastContentDetails();
MonitorStreamInfo monitorStream = new MonitorStreamInfo();
monitorStream.setEnableMonitorStream(false);
contentDetails.setMonitorStream(monitorStream);
LiveBroadcast broadcast = new LiveBroadcast();
broadcast.setKind("youtube#liveBroadcast");
broadcast.setSnippet(broadcastSnippet);
broadcast.setStatus(status);
broadcast.setContentDetails(contentDetails);
YouTube.LiveBroadcasts.Insert liveBroadcastInsert =
mService.liveBroadcasts().insert("snippet,contentDetails,status", broadcast);
LiveBroadcast returnedBroadcast = liveBroadcastInsert.execute();
// step 2 create live stream
String streamTitle = "Test Live Stream title";
LiveStreamSnippet streamSnippet = new LiveStreamSnippet();
streamSnippet.setTitle(streamTitle);
CdnSettings cdnSettings = new CdnSettings();
cdnSettings.setFormat("720p");
cdnSettings.setIngestionType("rtmp");
LiveStream stream = new LiveStream();
stream.setKind("youtube#liveStream");
stream.setSnippet(streamSnippet);
stream.setCdn(cdnSettings);
YouTube.LiveStreams.Insert liveStreamInsert =
mService.liveStreams().insert("snippet,cdn", stream);
LiveStream returnedStream = liveStreamInsert.execute();
if (returnedStream != null) {
YouTube.LiveBroadcasts.Bind liveBroadcastBind =
mService.liveBroadcasts().bind(returnedBroadcast.getId(), "id,snippet,contentDetails,status");
liveBroadcastBind.setStreamId(returnedStream.getId());
returnedBroadcast = liveBroadcastBind.execute();
String serverUrl = returnedStream.getCdn().getIngestionInfo().getIngestionAddress();
String streamName = returnedStream.getCdn().getIngestionInfo().getStreamName();
String rtmpUrl = serverUrl + "/" + streamName;
// use this rtmpUrl for streaming
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

signalr with sqldepdency firing multiple times for each browser instance

I am having a asp.net mvc app with vs2013 and .net framwork 4.5.1 which should notify users when a certain field gets updated and for a certain recordID.
Everything works fine when I have a single instance of the browser open, but when i open another tab or browser either on the same machine or on the different machine it fires the sqldepdencychange event multiple times.
Below is my hub code
public class MessagesHub : Hub
{
private static string conString = ConfigurationManager.ConnectionStrings["FleetLink_DB"].ToString();
private static string hostName = "";
public static void SendMessages(string hName)
{
IHubContext context = GlobalHost.ConnectionManager.GetHubContext<MessagesHub>();
hostName = hName;
context.Clients.Group(hostName).updateMessages(hName);
}
public Task leaveGroup(string hName)
{
return Groups.Remove(Context.ConnectionId, hName);
}
public Task joinGroup(string hName)
{
return Groups.Add(Context.ConnectionId, hName);
}
}
Below is my signalr script file
$(function () {
var dialog, form
// Declare a proxy to reference the hub.
var notifications = $.connection.messagesHub;
//debugger;
//Create a function that the hub can call to broadcast messages.
notifications.client.updateMessages = function (hName) {
alert("testing");
getoneMessages(hName)
};
$.connection.hub.logging = true;
$.connection.hub.start().done(function () {
var hostName = getUrlVars()["System_Name"];
notifications.server.joinGroup(hostName);
}).fail(function (e) {
alert(e);
});
});
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
function getoneMessages(hName) {
var tbl = $('#selectable');
//alert('mesgID=' + mesgID)
//var tbl = $('#selectable');
$.ajax({
url: '/controller/view',
cache: false,
contentType: 'application/html ; charset:utf-8',
type: 'GET',
dataType: 'html'
}).success(function (result) {
//alert(result);
tbl.empty().append(result);
}).error(function (exception) {
//alert('failed= ' + exception);
});
}
window.onbeforeunload = function (e) {
var hostName = getUrlVars()["System_Name"];
notifications.server.joinGroup(hostName);
$.connection.hub.stop();
};
Below is my partialview code along with the definition for RegisterForNotification and depdendency_onchange event
public PartialViewResult SignalRTesterPartialView()
{
/...COde not included for brevity..../
RegisterForNotifications(ID);
}
public void RegisterForNotifications(int mID)
{
var efConnectionString = ConfigurationManager.ConnectionStrings["DB"].ConnectionString;
var builder = new EntityConnectionStringBuilder(efConnectionString);
var regularConnectionString = builder.ProviderConnectionString;
string commandText = null;
commandText = "select ID,Status,Name from tblABC where ID=" + strID;
using (SqlConnection connection = new SqlConnection(regularConnectionString))
{
using (SqlCommand command = new SqlCommand(commandText, connection))
{
connection.Open();
var dependency = new SqlDependency(command);
dependency.OnChange += new OnChangeEventHandler(dependency_OnChange);
// NOTE: You have to execute the command, or the notification will never fire.
var reader = command.ExecuteReader();
}
}
}
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change && e.Info== SqlNotificationInfo.Update)
{
MessagesHub.SendMessages(hName);
}
RegisterForNotifications(1012);
}
Not sure why it is firing the sendmessages multiple times with each additional browser instance that I open. Any pointers would be helpful!
remove EventHandler when you done with it
private void dependency_OnChange(object sender, SqlNotificationEventArgs e)
{
if (e.Type == SqlNotificationType.Change && e.Info== SqlNotificationInfo.Update)
{
MessagesHub.SendMessages(hName);
}
//remove event handler
SqlDependency dependency = sender as SqlDependency;
dependency.OnChange -= new OnChangeEventHandler(dependency_OnChange);
RegisterForNotifications(1012);
}

android media player connecting status with audio streaming link(ie 2%,4%...100% then online radio start to play) in android

how i get buffering status while media player trying to connect audio streaming link(ie 2%,4%...100% then online radio start to play) in android.
this is my code.
but i have no idea how i solve my problem.thanks is advance to any kind of help.
player.setOnBufferingUpdateListener(new OnBufferingUpdateListener() {
public void onBufferingUpdate(MediaPlayer mp, int percent) {
playSeekBar.setSecondaryProgress(percent);
Log.i("Buffering", "" + percent);
}
});
i solve this problem. here is the link. http://coderfriend.blogspot.com/
as per request here i share blog content..
when user click play button to play radio then i want to show connecting status(buffering 1%,2%.. 99%). when status will be 100% radio start to play. i was face problem to solve this. so here i share this code for all.
//at first create this class
public class StreamingMediaPlayer {
private static final int INTIAL_KB_BUFFER = 96*10/8;//assume 96kbps*10secs/8bits per byte
private TextView textStreamed;
private ImageButton playButton;
private ProgressBar progressBar;
// Track for display by progressBar
private long mediaLengthInKb, mediaLengthInSeconds;
private int totalKbRead = 0;
// Create Handler to call View updates on the main UI thread.
private final Handler handler = new Handler();
private MediaPlayer mediaPlayer;
private File downloadingMediaFile;
private boolean isInterrupted;
private Context context;
private int counter = 0;
public StreamingMediaPlayer(Context context,TextView textStreamed, ImageButton playButton, Button streamButton,ProgressBar progressBar)
{
this.context = context;
this.textStreamed = textStreamed;
this.playButton = playButton;
this.progressBar = progressBar;
}
/**
* Progressivly download the media to a temporary location and update the MediaPlayer as new content becomes available.
*/
public void startStreaming(final String mediaUrl, long mediaLengthInKb, long mediaLengthInSeconds) throws IOException {
this.mediaLengthInKb = mediaLengthInKb;
this.mediaLengthInSeconds = mediaLengthInSeconds;
Runnable r = new Runnable() {
public void run() {
try {
downloadAudioIncrement(mediaUrl);
} catch (IOException e) {
Log.e(getClass().getName(), "Unable to initialize the MediaPlayer for fileUrl=" + mediaUrl, e);
return;
}
}
};
new Thread(r).start();
}
/**
* Download the url stream to a temporary location and then call the setDataSource
* for that local file
*/
public void downloadAudioIncrement(String mediaUrl) throws IOException {
URLConnection cn = new URL(mediaUrl).openConnection();
cn.connect();
InputStream stream = cn.getInputStream();
if (stream == null) {
Log.e(getClass().getName(), "Unable to create InputStream for mediaUrl:" + mediaUrl);
}
downloadingMediaFile = new File(context.getCacheDir(),"downloadingMedia.dat");
if (downloadingMediaFile.exists()) {
downloadingMediaFile.delete();
}
FileOutputStream out = new FileOutputStream(downloadingMediaFile);
byte buf[] = new byte[16384];
int totalBytesRead = 0, incrementalBytesRead = 0;
do {
int numread = stream.read(buf);
if (numread <= 0)
break;
out.write(buf, 0, numread);
totalBytesRead += numread;
incrementalBytesRead += numread;
totalKbRead = totalBytesRead/1000;
testMediaBuffer();
fireDataLoadUpdate();
} while (validateNotInterrupted());
stream.close();
if (validateNotInterrupted()) {
fireDataFullyLoaded();
}
}
private boolean validateNotInterrupted() {
if (isInterrupted) {
if (mediaPlayer != null) {
mediaPlayer.pause();
//mediaPlayer.release();
}
return false;
} else {
return true;
}
}
/**
* Test whether we need to transfer buffered data to the MediaPlayer.
* Interacting with MediaPlayer on non-main UI thread can causes crashes to so perform this using a Handler.
*/
private void testMediaBuffer() {
Runnable updater = new Runnable() {
public void run() {
if (mediaPlayer == null) {
// Only create the MediaPlayer once we have the minimum buffered data
if ( totalKbRead >= INTIAL_KB_BUFFER) {
try {
startMediaPlayer();
} catch (Exception e) {
Log.e(getClass().getName(), "Error copying buffered conent.", e);
}
}
} else if ( mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000 ){
// NOTE: The media player has stopped at the end so transfer any existing buffered data
// We test for < 1second of data because the media player can stop when there is still
// a few milliseconds of data left to play
transferBufferToMediaPlayer();
}
}
};
handler.post(updater);
}
private void startMediaPlayer() {
try {
File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");
// We double buffer the data to avoid potential read/write errors that could happen if the
// download thread attempted to write at the same time the MediaPlayer was trying to read.
// For example, we can't guarantee that the MediaPlayer won't open a file for playing and leave it locked while
// the media is playing. This would permanently deadlock the file download. To avoid such a deadloack,
// we move the currently loaded data to a temporary buffer file that we start playing while the remaining
// data downloads.
moveFile(downloadingMediaFile,bufferedFile);
Log.e(getClass().getName(),"Buffered File path: " + bufferedFile.getAbsolutePath());
Log.e(getClass().getName(),"Buffered File length: " + bufferedFile.length()+"");
mediaPlayer = createMediaPlayer(bufferedFile);
// We have pre-loaded enough content and started the MediaPlayer so update the buttons & progress meters.
mediaPlayer.start();
startPlayProgressUpdater();
playButton.setEnabled(true);
} catch (IOException e) {
Log.e(getClass().getName(), "Error initializing the MediaPlayer.", e);
return;
}
}
private MediaPlayer createMediaPlayer(File mediaFile)
throws IOException {
MediaPlayer mPlayer = new MediaPlayer();
mPlayer.setOnErrorListener(
new MediaPlayer.OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.e(getClass().getName(), "Error in MediaPlayer: (" + what +") with extra (" +extra +")" );
return false;
}
});
// It appears that for security/permission reasons, it is better to pass a FileDescriptor rather than a direct path to the File.
// Also I have seen errors such as "PVMFErrNotSupported" and "Prepare failed.: status=0x1" if a file path String is passed to
// setDataSource(). So unless otherwise noted, we use a FileDescriptor here.
FileInputStream fis = new FileInputStream(mediaFile);
mPlayer.setDataSource(fis.getFD());
mPlayer.prepare();
return mPlayer;
}
/**
* Transfer buffered data to the MediaPlayer.
* NOTE: Interacting with a MediaPlayer on a non-main UI thread can cause thread-lock and crashes so
* this method should always be called using a Handler.
*/
private void transferBufferToMediaPlayer() {
try {
// First determine if we need to restart the player after transferring data...e.g. perhaps the user pressed pause
boolean wasPlaying = mediaPlayer.isPlaying();
int curPosition = mediaPlayer.getCurrentPosition();
// Copy the currently downloaded content to a new buffered File. Store the old File for deleting later.
File oldBufferedFile = new File(context.getCacheDir(),"playingMedia" + counter + ".dat");
File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");
// This may be the last buffered File so ask that it be delete on exit. If it's already deleted, then this won't mean anything. If you want to
// keep and track fully downloaded files for later use, write caching code and please send me a copy.
bufferedFile.delete();
moveFile(downloadingMediaFile,bufferedFile);
// Pause the current player now as we are about to create and start a new one. So far (Android v1.5),
// this always happens so quickly that the user never realized we've stopped the player and started a new one
mediaPlayer.pause();
// Create a new MediaPlayer rather than try to re-prepare the prior one.
mediaPlayer = createMediaPlayer(bufferedFile);
mediaPlayer.seekTo(curPosition);
// Restart if at end of prior buffered content or mediaPlayer was previously playing.
// NOTE: We test for < 1second of data because the media player can stop when there is still
// a few milliseconds of data left to play
boolean atEndOfFile = mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() <= 1000;
if (wasPlaying || atEndOfFile){
mediaPlayer.start();
}
// Lastly delete the previously playing buffered File as it's no longer needed.
oldBufferedFile.delete();
}catch (Exception e) {
Log.e(getClass().getName(), "Error updating to newly loaded content.", e);
}
}
private void fireDataLoadUpdate() {
Runnable updater = new Runnable() {
public void run() {
if((totalKbRead>19)&&(totalKbRead<120))
textStreamed.setText((totalKbRead-19 + "% Buffering"));//show buffering status.. ie 1%,2%. in ui
else if(totalKbRead<19)
textStreamed.setText(("Connecting..."));
else
textStreamed.setText((""));
float loadProgress = ((float)totalKbRead/(float)mediaLengthInKb);
progressBar.setSecondaryProgress((int)(loadProgress*100));
}
};
handler.post(updater);
}
private void fireDataFullyLoaded() {
Runnable updater = new Runnable() {
public void run() {
transferBufferToMediaPlayer();
// Delete the downloaded File as it's now been transferred to the currently playing buffer file.
downloadingMediaFile.delete();
textStreamed.setText(("Audio full loaded: " + totalKbRead + " Kb read"));
}
};
handler.post(updater);
}
public MediaPlayer getMediaPlayer() {
return mediaPlayer;
}
public void startPlayProgressUpdater() {
float progress = (((float)mediaPlayer.getCurrentPosition()/1000)/mediaLengthInSeconds);
progressBar.setProgress((int)(progress*100));
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
startPlayProgressUpdater();
}
};
handler.postDelayed(notification,1000);
}
}
public void interrupt() {
playButton.setEnabled(false);
isInterrupted = true;
validateNotInterrupted();
}
/**
* Move the file in oldLocation to newLocation.
*/
public void moveFile(File oldLocation, File newLocation)
throws IOException {
if ( oldLocation.exists( )) {
BufferedInputStream reader = new BufferedInputStream( new FileInputStream(oldLocation) );
BufferedOutputStream writer = new BufferedOutputStream( new FileOutputStream(newLocation, false));
try {
byte[] buff = new byte[8192];
int numChars;
while ( (numChars = reader.read( buff, 0, buff.length ) ) != -1) {
writer.write( buff, 0, numChars );
}
} catch( IOException ex ) {
throw new IOException("IOException when transferring " + oldLocation.getPath() + " to " + newLocation.getPath());
} finally {
try {
if ( reader != null ){
writer.close();
reader.close();
}
} catch( IOException ex ){
Log.e(getClass().getName(),"Error closing files when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
}
}
} else {
throw new IOException("Old location does not exist when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
}
}
}
//now copy the below code in activity
StreamingMediaPlayer audioStreamer =
new StreamingMediaPlayer(this,textStreamed,playButton,
streamButton,progressBar);
audioStreamer.startStreaming("your streaming station name",5208, 216);
i think this helps you :)

How to send file with file name by use wifidirect?

I use wifidirect to send file,but I can't get the file name(include .jpg or .mp3),and sent it,it always null.
i'm using wifidirect demo provided Android Developers
I use
File f = new File(uri.getPath());
fileName = f.getName();
and
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ "Wifidirect" + "/" + fileName);
but fileName is alwas null
public class DeviceDetailFragment extends Fragment implements ConnectionInfoListener {
protected static final int CHOOSE_FILE_RESULT_CODE = 20;
private View mContentView = null;
private WifiP2pDevice device;
private WifiP2pInfo info;
//private static WiFiDirectBundle bundle = new WiFiDirectBundle();
ProgressDialog progressDialog = null;
private static String fileName;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContentView = inflater.inflate(R.layout.device_detail, null);
mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.deviceAddress;
config.wps.setup = WpsInfo.PBC;
config.groupOwnerIntent = 15;
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
"Connecting to :" + device.deviceAddress, true, true
// new DialogInterface.OnCancelListener() {
//
// #Override
// public void onCancel(DialogInterface dialog) {
// ((DeviceActionListener) getActivity()).cancelDisconnect();
// }
// }
);
((DeviceActionListener) getActivity()).connect(config);
}
});
mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
((DeviceActionListener) getActivity()).disconnect();
}
});
mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
// Allow user to pick an image from Gallery or other
// registered apps
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
}
});
return mContentView;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// User has picked an image. Transfer it to group owner i.e peer using
// FileTransferService.
Uri uri = data.getData();
File f = new File(uri.getPath());
fileName = f.getName();
TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
statusText.setText("Sending: " + uri);
Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
Intent serviceIntent = new Intent(getActivity(), FileTransferService.class);
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
info.groupOwnerAddress.getHostAddress());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
getActivity().startService(serviceIntent);
}
#Override
public void onConnectionInfoAvailable(final WifiP2pInfo info) {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
this.info = info;
this.getView().setVisibility(View.VISIBLE);
// The owner IP is now known.
TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
view.setText(getResources().getString(R.string.group_owner_text)
+ ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
: getResources().getString(R.string.no)));
// InetAddress from WifiP2pInfo struct.
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
// After the group negotiation, we assign the group owner as the file
// server. The file server is single threaded, single connection server
// socket.
if (info.groupFormed && info.isGroupOwner) {
new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
.execute();
} else if (info.groupFormed) {
// The other device acts as the client. In this case, we enable the
// get file button.
mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
.getString(R.string.client_text));
}
// hide the connect button
mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
}
/**
* Updates the UI with device data
*
* #param device the device to be displayed
*/
public void showDetails(WifiP2pDevice device) {
this.device = device;
this.getView().setVisibility(View.VISIBLE);
TextView view = (TextView) mContentView.findViewById(R.id.device_address);
view.setText(device.deviceAddress);
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText(device.toString());
}
/**
* Clears the UI fields after a disconnect or direct mode disable operation.
*/
public void resetViews() {
mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
TextView view = (TextView) mContentView.findViewById(R.id.device_address);
view.setText(R.string.empty);
view = (TextView) mContentView.findViewById(R.id.device_info);
view.setText(R.string.empty);
view = (TextView) mContentView.findViewById(R.id.group_owner);
view.setText(R.string.empty);
view = (TextView) mContentView.findViewById(R.id.status_text);
view.setText(R.string.empty);
mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
this.getView().setVisibility(View.GONE);
}
/**
* A simple server socket that accepts connection and writes some data on
* the stream.
*/
public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
private Context context;
private TextView statusText;
//String FileName = "bundle.fileName";
/**
* #param context
* #param statusText
*/
public FileServerAsyncTask(Context context, View statusText) {
this.context = context;
this.statusText = (TextView) statusText;
}
#Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
Socket client = serverSocket.accept();
Log.d(WiFiDirectActivity.TAG, "Server: connection done");
/*final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ "Wifidirect" + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");*/
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ "Wifidirect" + "/" + fileName);
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
Log.e(WiFiDirectActivity.TAG, e.getMessage());
return null;
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
if (result != null) {
statusText.setText("File copied - " + result);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + result), "image/*");
context.startActivity(intent);
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
statusText.setText("Opening a server socket");
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
Log.d(WiFiDirectActivity.TAG, e.toString());
return false;
}
return true;
}
}
File f = new File(uri.getPath());
fileName = f.getName();
This part of code in your app will get executed - if device acts as client
and
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ "Wifidirect" + "/" + fileName);
this part of code in your app will get executed - if device acts as server (in this case GO) but fileName is always null
Since filename is initialized to "null" , on the server device this will be null.
FileServerAsyncTask is created only on GO( server ) as per the code.
In android sample code file transfer is working only from client to server. In this code user can do file sharing in both directions i.e client to server as well as server to client.
You can see this link.
How can I transfer files between Android devices using Wi-Fi Direct?

C# Web Cam with Remoting

My project is about Remoting and i want to add a webcam component to it. Here it goes: I have 3 project in my solution... Client, Server, Remote.dll. In Remote.dll is a common class which has methods works in server machine. When i call these methods from Client it executes in server side. So now my question is i put the code of Webcam in remote.dll and it has an event called "video_NewFrame" which it works everytime when webcam catch an image. But i cant reach to the images from my Client side because when code drops to this event it executes infinitely
and my timer in Client side doesnt work as well. I tried to assing image to my global variable but whenever code goes to client and comes to Remote.dll again my variable is null...
How can i reach simultaneously captured images from my client? here is my code:
(i use AForge framework for webcam)
private bool DeviceExist = true;
private FilterInfoCollection videoDevices;
private VideoCaptureDevice videoSource = null;
public bool WebCamStart(int DeviceIndex)
{
if (DeviceExist)
{
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
//string myDevice = videoDevices[0].Name;
videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString);
videoSource.NewFrame += new NewFrameEventHandler(video_NewFrame);
CloseVideoSource();
videoSource.DesiredFrameSize = new Size(640, 480);
//videoSource.DesiredFrameRate = 10;
videoSource.Start();
return true;
}
else return false;
}
public Bitmap lastImg;
private void video_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
Bitmap img = (Bitmap)eventArgs.Frame.Clone();
//in executes infinitely when execution comes here and i cant reach from Cliend side...
}
public string getFPS()
{
return videoSource.FramesReceived.ToString();
}
public void CloseVideoSource()
{
if (!(videoSource == null))
if (videoSource.IsRunning)
{
videoSource.SignalToStop();
videoSource.Stop();
videoSource = null;
}
}
public string getCamList()
{
string result = "No Device Found";
try
{
videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
//comboBox1.Items.Clear();
if (videoDevices.Count == 0)
throw new ApplicationException();
DeviceExist = true;
foreach (FilterInfo device in videoDevices)
{
//comboBox1.Items.Add(device.Name);
result = device.Name;
return result;
}
//comboBox1.SelectedIndex = 0; //make dafault to first cam
}
catch (ApplicationException)
{
DeviceExist = false;
//comboBox1.Items.Add("No capture device on your system");
return "No capture device on your system";
}
return result;
}
// and my client side...
private void timerWebCam_Tick(object sender, EventArgs e)
{
//lblFPS.Text ="Device Running... " + remObj.getFPS() + " FPS";
pictureBox1.Image = remObj.lastImg;
}