I have a use case, where in after sending the video stream to the Red5 server, I would like to post process on the video after the video is saved. I would like to add some metadata tags on them.
I found that this can be done in appDisconnect() method in the ApplicationAdapter, but there are other ways via which the video can be saved like by using ClientBroadcastStream also.
Example
ClientBroadcastStream stream = (ClientBroadcastStream) app.getBroadcastStream(
conn.getScope(), "hostStream");
// Stop recording
stream.stopRecording();
I would like to know if there are any events which I can listen on (like which tells me that video is saved and is saved in this location with this filename) to do post-processing of the video. So that I need not put hooks in multiple places.
Thanks
The "ez" way is to implement your own ClientBroadcastStream by extending this base class. Then simply override the "stopRecording()" method. If you would like to take a moment and add an enhancement request on the issue tracker, I would be glad to look into adding scope events for this type of thing. With a scope event you could just listen for them anywhere and handle them appropriately. Red5 issue tracker: http://code.google.com/p/red5/issues/list
Using a custom stream class would be configured in the red5-common.xml like so:
<bean id="clientBroadcastStream" scope="prototype" lazy-init="true" class="com.mypackage.MyClientBroadcastStream">
</bean>
Related
I am making some light video editing in swift 4, reading the video with AVAsset() and then using the AVExportSession to export the result. Everything works fine except one thing: the resulted video keeps the metadata of the original video.
This metadata includes (for example) the time and location where the video was taken.
I saw that the AVExportSession has a metadata:[AVMetadataItem] property, but I don't know how to use it. I set it to nil and it didn't work, it still keept the old metadata.
I read the apple's documentation about and it says that you don't create instances nor can modify a metadata item, so how can I do? how can I erase that metadata or write new generated metadata to it?
There is a lot of info about reading metadata, but not much on writing it.
Thanks in advance.
Aditional links
https://developer.apple.com/documentation/avfoundation/avassetexportsession
You can filter metadata with AVMetadataItemFilter.forSharing().
From the spec: Removes user-identifying metadata items, such as location information and leaves only metadata releated to commerce or playback itself. (see https://developer.apple.com/documentation/avfoundation/avmetadataitemfilter/1387905-forsharing)
Just add it to your export session:
let exportSession = AVExportSession() // choose your appropriate init
exportSession.metadataItemFilter = AVMetadataItemFilter.forSharing()
I've set a custom client for a FLVPlayback's netStream, to attach my own functions (onXMPData, onMetaData) to parse the various info myself. However, i'd still like to pass the meta data back to the VideoPlayer. How do I do this? I tried dispatching a METADATA_RECEIVED event with the metadata object (tried dispatching from the client, the netstream, the video player, the flvplayback..), but it does not work.
I gave up, and decided just to open two netstreams for the f4v. The regular, untampered flvplayback one.. and then another just for reading xmpdata.
I'm trying to figure out how I can specify a custom end time for an embedded YouTube video. I know that I can customize the start time by adding &start=30, but I haven't seen anything relating to the end time.
I need to be able to do this for a web app I'm building, so if there is no way provided by YouTube, how might I be able to accomplish this anyway?
I've skimmed over the documentation to no avail. Thanks!
I just found out that the following works:
https://www.youtube.com/embed/[video_id]?start=[start_at_second]&end=[end_at_second]
Note: the time must be an integer number of seconds (e.g. 119, not 1m59s).
I tried the method of #mystic11 ( https://stackoverflow.com/a/11422551/506073 ) and got redirected around. Here is a working example URL:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3
If the version=3 parameter is omitted, the video starts at the correct place but runs all the way to the end. From the documentation for the end parameter I am guessing version=3 asks for the AS3 player to be used. See:
end (supported players: AS3, HTML5)
Additional Experiments
Autoplay
Autoplay of the clipped video portion works:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3&autoplay=1
Looping
Adding looping as per the documentation unfortunately starts the second and subsequent iterations at the beginning of the video:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3&loop=1&playlist=WA8sLsM3McU
To do this properly, you probably need to set enablejsapi=1 and use the javascript API.
FYI, the above video looped: http://www.infinitelooper.com/?v=WA8sLsM3McU&p=n#/15;19
Remove Branding and Related Videos
To get rid of the Youtube logo and the list of videos to click on to at the end of playing the video you want to watch, add these (&modestBranding=1&rel=0) parameters:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3&autoplay=1&modestBranding=1&rel=0
Remove the uploader info with showinfo=0:
http://youtube.googleapis.com/v/WA8sLsM3McU?start=15&end=20&version=3&autoplay=1&modestBranding=1&rel=0&showinfo=0
This eliminates the thin strip with video title, up and down thumbs, and info icon at the top of the video. The final version produced is fairly clean and doesn't have the downside of giving your viewers an exit into unproductive clicking around Youtube at the end of watching the video portion that you wanted them to see.
Use parameters(seconds) i.e. youtube.com/v/VIDEO_ID?start=4&end=117
Live DEMO:
https://puvox.software/software/youtube_trimmer.php
Youtube doesn't provide any option for an end time, but there alternative sites that provide this, like
Tubechop. Otherwise try writing a function that either pauses video/skips to next
when your when your video has played its desired duration.
OR: using the Youtube Javascript player API, you could do something like this:
function onPlayerStateChange(evt) {
if (evt.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo, 6000);
done = true;
}
}
Youtube API blog
Today I found, that the old ways are not working very well.
So I used:
"Customize YouTube Start and End Time - Acetrot.com"
from http://www.youtubestartend.com/
They provide a link into
https://xxxx.app.goo.gl/yyyyyyyyyy
e.g. https://v637g.app.goo.gl/Cs2SV9NEeoweNGGy9
Link contain forward to format like this
https://www.youtube.com/embed/xyzabc123?start=17&end=21&version=3&autoplay=1
I was just trying to look up how and found there is a CLIP feature now added by Youtube right under the video that I had never noticed before!
I use this signature:
youtube.com/embed/[YOUR_VIDEO_ID]?start=[TIME_IN_SEC]&end=[TIME_IN_SEC]&autoplay=1
https://www.youtube.com/embed/2EWejmkKlxs?start=1230&end=1246&autoplay=1
I use dephi7's client/server socket components to send a file with tfilestream from client to server.
I'am able to get the progress of file received at server side,
but at client side, how do i get the progress of the file sent ?
this is how I send the file:
fstream:=tfilestream.Create(opendialog1.FileName,fmOpenRead);
clientsocket1.Socket.SendStream(fstream);
Thanks and appreciate for any help.
It doesn't look like TClientSocket provides any feedback of its progress. I see two alternatives:
Instead of SendStream, use TStream.Read and TClientSocket.Socket.SendBuf in a loop. Read a block of data from the stream and then send it. Repeat until you reach the end of the stream.
Write a TStream descendant class that wraps (or decorates) another stream. Its Read, Write, and Seek methods can simply forward to the wrapped stream, but you can also add some events to the wrapper so you can be notified each time the socket code reads a block of data out of the stream — the SendStream method essentially does the same thing that I described above in the first alternative.
Using the youtube javascript api (http://code.google.com/apis/youtube/js_api_reference.html), I am trying to allow a user to embed a video into some content he creates in my app. I have gotten everything working, except for being able to detect and handle the case that embedding is not allowed for the video.
Currently, the player loads and shows a thumbnail of the disallowed video, and it only gives an error once the user tries to play it. This is bad because the user may not play the video before saving / sending his content. I would like to preemptively detect that the video is not allowed to be embedded, and display a helpful message to the user.
The only solution I can see is to actually play it (programmatically) and handle the error that is raised at that point.
Existing workaround:
Embed player (embedSWF)
onYouTubePlayerReady(): add onError onStateChange event listeners.
onStateChange(newState): when the video finishes loading, try to play it.
e.g. if (newState == 5 /* CUED */) { player.mute(); player.playVideo(); player.stopVideo(); player.unMute(); }
onError(error): if the video failed to play in onStateChange, will receive error here.
Is there a better way?
Thanks!
-Rob
You can grab the JSON feed for that video entry before you embed it and see if "yt$format":5 exists, which is the embed SWF. It won't be there if embedding is disabled.
http://gdata.youtube.com/feeds/api/videos/video_id?v=2&alt=json-in-script
I think that you might be looking for the videoSyndicated or the videoEmbeddable parameter. The API documentation says:
videoEmbeddable
The videoEmbeddable parameter lets you to restrict a search to only videos that can be embedded into a webpage. If you specify a value for this parameter, you must also set the type parameter's value to video.
Reference: https://developers.google.com/youtube/v3/docs/search/list#videoEmbeddable
videoSyndicated
The videoSyndicated parameter lets you to restrict a search to only videos that can be played outside youtube.com. If you specify a value for this parameter, you must also set the type parameter's value to video.
Reference: https://developers.google.com/youtube/v3/docs/search/list#videoSyndicated
Example Call
With both:
GET https://www.googleapis.com/youtube/v3/search?&part=snippet,statistics&videoSyndicated=true&videoEmbeddable=true&key=${yourKey}
I know this isn't directly to the question, but in case someone using PHP stumbles upon this problem, there's a method getNoEmbed() in a Zend_Gdata_YouTube_VideoEntry.
Taken from the docs:
If the return value is an instance of Zend_Gdata_YouTube_Extension_NoEmbed, this video cannot be embedded.