I am currently on working on my university project which involves GStreamer audio streaming.
I have successfully managed to get streaming working between client/server and TCP.
My next task is to dynamically change the audio stream on user input.
I tried the following:
pp.setState(State.PAUSED);
pp.setState(State.READY);
pp.unlink(src);
source = ElementFactory.make("filesrc", "src");
pp.link(source);
source.set("location", fpath);
pp.setState(State.PLAYING);
fpath is the audio file location. When a user input is received, the state is set to PAUSE, the source is unlinked and a new source is added. The state is set to PLAYING.
I used GST_DEBUG on client side and there are no errors, buffers are sent to the client but no sound.
Any suggestions would be appreciated.
You don't need to unlink and add a new source. Just go straight to READY (no need to go to PAUSED and then to READY, this will happen implicitly), set a new location and go back to playing.
you need to syncStateWithParent();.
I am using it for different purpose but this can be extended to your application on property change Gstreamer: Pausing/resuming video in RTP streams
Related
I have users connected to the voice channel "waited" and I would like to move them to another channel. How to do it? Is it supported by discord4j?
Look at GuildMemberEditSpec. There is a command setNewVoiceChannel that can be used to move the user to a new voice channel.
I have a Java batch process which scans a directory and automatically uploads videos to YouTube using the v3 API. The jobs processes a few hundred videos a day. Of those uploaded 20-50% result in the grey ellipse icon and eventually the error "Failed (unable to convert video file)".
The videos are all mp4 format. The videos all utilize the same API process which I will outline below. The videos range between ~70MB & 150MB.
The process:
Authorize for Upload "https://www(dot)googleapis(dot)com/auth/youtube.upload", Set privacy to public, Set Snippet (Set channel, Set Title, Set Description, Set Tags)
InputStream buffInStream = new BufferedInputStream(new FileInputStream(fileName));
AbstractInputStreamContent mediaContent = new InputStreamContent(MarketingConstants.YT_VIDEO_FORMAT, buffInStream);
YouTube.Videos.Insert videoInsert = youtube.videos().insert("snippet,statistics,status", videoMetadata, mediaContent);
videoInsert.setNotifySubscribers(false);
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
// Set direct upload to TRUE and the job is remarkably efficient 2500kb/second (FAST)
// Set to False, and the job is horribly inefficient 70kb/second (SLOW)
uploader.setDirectUploadEnabled(true);
Video returnedVideo = videoInsert.execute();
Upon successful completion, update video data:
Authorize for Update "https://www(dot)googleapis(dot)com/auth/youtube", Get previously uploaded Video Id, Get snippet for said Video Id, Replace description with updated one (the job creates a tagged url for the description that incorporates the video id, hence the reason to update).
snippet.setDescription(newDescription);
// Update the video resource by calling the videos.update() method
YouTube.Videos.Update updateVideosRequest = youtube.videos().update("snippet,status", video);
Video videoResponse = updateVideosRequest.execute();
Finally, the process adds the video to a specific playlist within the original Channel based on content specifics. To do this, it will Authorize for playlist update "https://www(dot)googleapis(dot)com/auth/youtube", find associated playlist id based on category (these are properties within the process), and update.
ResourceId resourceId = new ResourceId();
// Identifies this as a video, required for adding to playlist
resourceId.setKind("youtube#video");
resourceId.setVideoId(videoId);
PlaylistItemSnippet playlistItemSnippet = new PlaylistItemSnippet();
playlistItemSnippet.setPlaylistId(playlistId);
playlistItemSnippet.setResourceId(resourceId);
PlaylistItem playlistItem = new PlaylistItem();
playlistItem.setSnippet(playlistItemSnippet);
//Add to the playlist
YouTube.PlaylistItems.Insert playlistItemsInsert = youtube.playlistItems().insert("snippet,contentDetails", playlistItem);
PlaylistItem returnedPlaylistItem = playlistItemsInsert.execute();
The only difference I can see with the uploaded videos that fail versus succeed is in the logging.
For a successful upload:
2015-11-22 09:18:35:694|YouTubeMediaService.uploadFileToYouTube()|Upload in progress
2015-11-22 09:19:27:158|YouTubeMediaService.uploadFileToYouTube()|Upload Completed!
That was ~52 seconds.
For a failure upload:
2015-11-22 07:31:12:182|YouTubeMediaService.uploadFileToYouTube()|Upload in progress
2015-11-22 07:31:43:847|YouTubeMediaService.uploadFileToYouTube()|Upload Completed!
That was ~32 seconds.
It appears that the faster it uploads (closer to 30 seconds), the more likely it is to fail. I do see some that take longer and still fail, but this is the only anomaly I've discovered.
Originally the process would set the privacy to private, then only set to public after successfully updating the information, but Google suggested we remove that due to a known glitch that can occur with switching the privacy settings.
So here's my question:
What do you suggest I do to mitigate this issue and ultimately achieve a successful upload rate closer to 95% or higher?
Should I remove the privacy portion all together? Should I retry videos that upload too fast, e.g. remove the recently uploaded video, wait 10 seconds, then try again?
Has anyone else encountered this issue, specifically with batch/automatic uploading? Thank you for any assistance.This shows the uploaded and failed videos (titles removed)
Does the native code of the VideoView give access to the received packets of the video before or after decoding it? I need to access these packets in order to transmit them to another device. The initial solution is to modify the Android native code. Other possible solutions that I found are to use GStreamer or FFmpeg libraries.
I need bit guidance in order to achieve that goal.
Assume the phone is rooted.
Short answer is no, not that I know of.
Long answer is that you haven't given enough detail. What data exactly do you need access to? Are you writing an application, or modifying your OS to do this to other applications?
The code that actually fetches a remote video is in MediaPlayer and is native. See the following method in MediaPlayer:
private void setDataSource(/* snip */) throws /* snip */ {
/* snip */
else if (scheme != null) {
// handle non-file sources
nativeSetDataSource(
MediaHTTPService.createHttpServiceBinderIfNecessary(path),
path,
keys,
values);
return;
}
/* snip */
Unfortunately for you, almost all of the relevant MediaPlayer code is native, and if not, it is private (so subclassing will not work here).
However, depending on what you need to do, you could possibly override VideoView method setVideoURI(Uri, Map<String, String>), which is public. Here you can grab the URI and then proxy it through your own web service, or something. This isn't quite what you were asking, though.
Or, you could possibly look into modifying the Surface that is drawn to by MediaPlayer. Most of the relevant code is still native though.
The final possibility that I'll mention (there are probably hundreds of possible approaches) would be to modify the MediaHTTPService class. This appears to be used by MediaPlayer, but I can't be sure because if it's used, it's used in native code.
This answer recommends finding the native code at androidxref.com
Edit:
As requested, here is a little more detail about what the "proxy server" solution might look like. I don't know the implementation details on Android.
Basically, when you get a URL to play in the VideoView, you pass it to your own server instead. Something like startProxyServer(videoUrl). This starts a server, which downloads and then re-hosts the video. To get this working locally, start a webserver listening on localhost. The server just downloads the video at videoUrl, saves it locally, and then hosts it at localhost:port/?video=${videoUrl}.
So in very high-level pseudo-code the server could look like.
public void startProxyServer(String videoUrl) {
int PORT = 28641; // random port
File f = downloadFile(videoUrl);
saveFile(f, '/path/to/server/storage');
startWebServer('localhost', PORT);
}
So now you give localhost:port/?video=${videoUrl} as url to the videoView instead. Also, now other videoView instances can download from that same localhost url.
To make it work with other phones, your server of course couldn't run on localhost.
Of course I've not implemented this, but it's just one solution I can think of.
I want two applets..
Transmitter applet which transmit the user's screen+audio from mic to getParameter("IP") and getParameter("PORT"). transmition is done after user's click on a "transmit" button and approval.
Receiver applet which receives the transmission from getParameter("IP") and getParameter("PORT") and play it with volume,play/pause,full-screen controls. and can save the stream into mpeg file.
Can anyone suggest how to stream in java from applet to applet?
Thank You,
Ronak
I Useed ROBOT Class and JMF..
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/Robot.html
http://grack.com/downloads/school/enel619.10/report/java_media_framework.html
I'm trying to use vlcj to play live internet radio stations in a project. I've played around with some sample programs for a few hours, but I cannot get either the sample programs or programs that I've played around with to play the stream from the URL.
An example of a URL I'm trying to play is: http://network.absoluteradio.co.uk/core/audio/wmp/live.asx?service=vr
Is there anything special I have to do in order to get vlcj to play this stream? I couldn't find anything to help in the API. (Assuming it can because it can be played through the VLC media player!)
Thanks a lot
Ok, the MRL you have provided us http://network.absoluteradio.co.uk/core/audio/wmp/live.asx?service=vr is a MMS server that may pull a ASX (XML) metafile which may contain at least one sub-item.
http://all-streaming-media.com/faq/streaming-media/Metafiles-ASX-Advanced-Stream-Redirector.htm
To be able to play this type of streaming media and go through each sub-item, you need to do the following code snippet:
VideoPanel.getMediaPlayer().setRepeat(true);
VideoPanel.getMediaPlayer().setPlaySubItems(true);
VideoPanel.getMediaPlayer().prepareMedia(media, options);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(String s: VideoPanel.getMediaPlayer().subItems()) System.out.println(s);
VideoPanel.getMediaPlayer().play();
For the example MRL above, it will list down all sub-items as follows:
http://wms.absoluteradio.co.uk/g1/absoluteradio.co.uk/prerolls/ar_account_1310455302_hi.wma
mms://wms.absoluteradio.co.uk/absoluteradio.co.uk/vr_lo?u=
http://wms.absoluteradio.co.uk/absoluteradio.co.uk/vr_lo?u=
mmsu://wms.absoluteradio.co.uk/absoluteradio.co.uk/vr_lo?u=
mmst://wms.absoluteradio.co.uk/absoluteradio.co.uk/vr_lo?u=
mms://wms.absoluteradio.co.uk/absoluteradio.co.uk/prerolls/problems_lo.wma
To stop playing all of them, set the following code snippet:
VideoPanel.getMediaPlayer().setRepeat(false);
VideoPanel.getMediaPlayer().setPlaySubItems(false);
VideoPanel.getMediaPlayer().stop();
For a better explanation, refer to: http://code.google.com/p/vlcj/wiki/HowToHandleYouTubeMedia
You cannot use the http to play such link directly. You will ve to use the port number of the radio station router. this is because if i want to receive my home live video streaming from the internet at my workplace, i type the following on url: http://my dns server ip address:8080 The 8080 is the port number I opened on my router.