14 Replies Latest reply on Dec 4, 2013 1:11 PM by Digiflare

    OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work

    Digiflare

      Hi 

       

      I'm having trouble getting dynamic streaming resources to automatically switch bitrates during playback. This mainly affects MP4 type videos.

      The video stream being played stays at the same bitrate forever and never switches despite the network speed being more than adequate.

      This problem only occurs when I construct the DynamicStreamingResource manually in the code.

       

      When I use a MediaFactory to read a F4M video stream, it is able to properly auto switch bitrates appropriately when playing back.

       

      I am manually constructing the DynamicStreamingResource in the code and pulling the video sources from a 3rd party web service. I'm placing these video file paths and their respective bitrates into individual DynamicStreamingItems which are then placed into the DynamicStreamingResources' resource vector.

       

      This is what the DynamicStreamingResource object would contain:

       

      DynamicStreamingResource()

      {

      Vector[0] = new DynamicStreamingItem(“rtmp://video1.mp4”, 100)

      Vector[1] = new DynamicStreamingItem(“rtmp://video2.mp4”, 200)

      Vector[2] = new DynamicStreamingItem(“rtmp://video3.mp4”, 300)

      Vector[3] = new DynamicStreamingItem(“rtmp://video4.mp4”, 400)

      }

       

      After I attach MetaData for an Akamai authentication token, I then feed the DynamicStreamingResource object into a MediaFactory that has loaded the AkamaiBasicStreamingPlugin because the videos are hosted through Akamai.

       

      The MediaFactory class returns a MediaElement that is Akamai authentication token compatible and I type coerce it into a VideoElement so I can use the smoothing and deblocking features on the video.

       

      At this point, everything works when playing back except for auto bitrate switching.

       

      Can anyone make any suggestions?

       

      Thanks

        • 1. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
          David_RealEyes

          Does the bitrate switching work if you are not using the Akamai plugin?

           

          It would be good to try and isolate out where the breakage is happening.

           

          I havnt had to use a manual DynamicStreamingResource in a long time so not sure off hand what could be wrong.

          • 2. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
            wovencharlie

            There are a few points of failure with bitrate switching, some in code, some at the CDN level.

             

            A few things you can do to test / debug would be to try and test each item individually first to be sure that the items are on the server.

             

            for instance you might try:

             

            DynamicStreamingResource()

            {

            Vector[0] = new DynamicStreamingItem(“rtmp://video4.mp4”, 400)

            }

             

            If that works, try placing a debug point after your MediaElement is returned from the MediaFactory and the token have been created to ensure it has the - MediaTraitType.DYNAMIC_STREAM

             

            Another option would be to put a listener on the MediaElement to listen for when these traits are added and then ensure that all the elements are there:

             

            I've used similar code to below but just wrote this without context so it may need some modification:

             

            First add a listener:

            element.addEventListener(MediaElementEvent.TRAIT_ADD, traitAdded);

             

            A better view of this code:http://pastebin.com/U6104iVR

             

            Then listen :-D:

            function traitAdded(event:MediaElementEvent):void {

            var element:VideoElement;//should be your video element

                      if (event.traitType === withTrait){

                                var dynamicStreamTrait:DynamicStreamTrait = element.getTrait(event.traitType) as DynamicStreamTrait;

              //Make sure autoSwich is true

                                dynamicStreamTrait.autoSwitch = true;

                                dynamicStreamTrait.switchTo(1);

             

              trace("-----")

                                trace(dynamicStreamTrait.getBitrateForIndex(0));

                                trace(dynamicStreamTrait.getBitrateForIndex(1));

                                trace(dynamicStreamTrait.getBitrateForIndex(2));

              trace("-----")

                                dynamicStreamTrait.addEventListener(DynamicStreamEvent.SWITCHING_CHANGE, function(evt:DynamicStreamEvent):void {

                                          if (evt.switching){

              trace("Dynamic stream switching in progress");

                                          } else {

                                                    trace("Dynamic stream switched to", dynamicStreamTrait.getBitrateForIndex(dynamicStreamTrait.currentIndex));

                                          }

                                });

             

                      }

            }

            • 3. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
              Digiflare Level 1

              Wow, thanks guys!

               

              wovencharlie, your solution was able to directly help me verify that the streams are actually switching by listening to the MediaTraitType.DYNAMIC_STREAM constant.

               

              What I did notice was that the quality of the videos remained the same as before I was able to verify that they're switching after my debugger console notified me of the switch.

               

              Therefore, I suspect that the auto switching had been happening all along except there just wasn't any way to actually verify it as maybe perhaps the listener I was using didn't listen for stream switches for DynamicStreamResource types.

              • 4. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                Digiflare Level 1

                Now that I have determined that auto switching actually works - it shows me that the problem actually was that the autoswitcher always seems to choose the lowest bitrate available despite the ample amounts of bandwidth I have available.

                 

                The original problem was that I thought it wasn't switching bitrates because it would always be at the lowest bitrate but it seems autoswitching is functional, just that it chooses the wrong bitrate.

                 

                I can't think of any reason why it would do this. Do you have any suggestions?

                • 5. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                  David_RealEyes Level 1

                  does it eventually switch from the lowest? it could just be the initial selection which you can control. Otherwise its related to the switching rules which takes in account bandwidth, target bitrate as well as dropped frames.

                  • 6. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                    Digiflare Level 1

                    Once it gets to the lowest bitrate, it doesn't switch upwards. I suspect it has something to do with the way the metrics are being calculated.

                     

                    I do have access to the netstream object and when I check its NetStreamInfo object, it tells me that the data buffer length is zero for up to 8 seconds before it fills it with bytes at an interval.

                     

                    It would look like this:

                     

                    1349253

                    1349253

                    0

                    0

                    0

                    0

                    0

                    0

                    0

                    • 7. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                      nweber_dp

                      So ABR really has two parts; being able to actually switch bitrates and then the rules which cause the switch to happen.  Now that you've verified that the DynamicStream trait exists and that auto switching is turned on, you should verify that you can force the bitrate to change.  If you can force the bitrate to change that means the issue must be in the ABR rules.

                       

                      Here's some code to force a bitrate switch:

                       

                      private function onBitrateDownClick(event:Event):void {

                          if (player.currentDynamicStreamIndex > 0) {

                              player.switchDynamicStreamIndex(player.currentDynamicStreamIndex - 1);

                          }

                      }

                       

                      private function onBitrateUpClick(event:Event):void {

                          if (player.currentDynamicStreamIndex < player.maxAllowedDynamicStreamIndex) {

                              player.switchDynamicStreamIndex(player.currentDynamicStreamIndex + 1);

                          }

                      }

                      • 8. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                        Digiflare Level 1

                        Hi nweber_dp

                         

                        I have been able to verify that I can manually switch bitrates. I highly suspect it is something to do with the ABR rules.

                        • 9. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                          nweber_dp Level 1

                          In that case, the rules are defined in RTMPDynamicStreamingNetLoader.as line 142.

                           

                          private function getDefaultSwitchingRules(metrics:RTMPNetStreamMetrics):Vector.<SwitchingRuleBase>

                          {

                                                        var rules:Vector.<SwitchingRuleBase> = new Vector.<SwitchingRuleBase>();

                                                        rules.push(new SufficientBandwidthRule(metrics));

                                                        rules.push(new InsufficientBandwidthRule(metrics));

                                                        rules.push(new DroppedFramesRule(metrics));

                                                        rules.push(new InsufficientBufferRule(metrics));

                                                        return rules;

                          }

                           

                          You could put logging / break points in each rule to see what the calculations are returning.  This is likely your best bet to figure out what about your streams or network is causing the rules to not function properly.

                           

                          It could also be possible that the RTMPDynamicStreamingNetLoader is not building the rules properly and perhaps they are not triggering at all.

                          • 10. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                            Digiflare Level 1

                            I had a thought come up after reading your last post nweber_dp but I'm having a bit of trouble implementing it.

                             

                            I'm constructing the DynamicStreamResource and passing it along with an Akamai authentication token MetaData through the MediaFactory in order to generate a MediaElement type. Then in order to gain access to the smoothing and deblocking filters, I type coerce it into a VideoElement type.

                             

                            var videoElement:VideoElement = mediaFactory.createMediaElement(dynResource) as VideoElement;

                             

                            However, since I am type casting it into a VideoElement, I haven't been able to specify the NetLoader type that I want to use. I want to try using the RTMPDynamicStreamingNetLoader to handle the metrics for this since it is a RTMP video stream.

                             

                            My suspicion is that the incorrect NetLoader type is being used by the VideoElement.

                             

                            However, in order to gain access to the videoElement.loader's protected property, I have to create a subclass of VideoElement so I can explicitly set the loader property. This seems to be a presenting a problem that causes a TypeError: Error #1009: Cannot access a property or method of a null object reference.

                             

                            I've tried all sorts of constructor combos but it still throws the same error. I'm almost convinced this is the solution to the auto switching problem. Once I can explicitly use the RTMPDynamicStreamingNetLoader, it should switch properly.

                             

                            The only problem is that I'm not sure why it keeps throwing a #1009 error. Does anyone have any suggestions?

                             

                             

                             

                            This is how I'm inheriting the VideoElement class:

                             

                             

                             

                                 import org.osmf.elements.VideoElement;

                                      import org.osmf.traits.LoaderBase;

                                      import org.osmf.net.rtmpstreaming.RTMPDynamicStreamingNetLoader;

                                      import org.osmf.media.MediaResourceBase;

                                      import org.osmf.net.NetLoader;

                             

                                      public class CustomVideoElement extends VideoElement

                                      {

                             

                                                public function CustomVideoElement(resource:MediaResourceBase = null, loader:NetLoader = null)

                                                {

                                                          super(null, null);

                                                          super.loader = new RTMPDynamicStreamingNetLoader();

                             

                                                          this.resource = resource;

                             

                             

                                                }

                                      }

                            • 11. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                              nweber_dp Level 1

                              It probably is the fact that you are creating the DynamicStreamingResource manually instead of letting the factory do it.  Are you doing this because you only have stream urls and not an f4m?  One thing you could try would be to create an F4M xml dynamically and then pass it to a StreamingXMLResource.  This should, I think, end up with the same element as if you passed an f4m URL.

                               

                              I believe you should be able to add your akamai authentication token metadata to the StreamingXMLResource instance and it should cascade down to whatever object OSMF ends up playing.

                              • 12. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                                Digiflare Level 1

                                Hi nweber_dp

                                 

                                Yes, the token, filepath names and bitrates are all provided to me via a JSON object from a 3rd party web service and not in any recognizable media manifest file. I take all the information and construct a DynamicStreamingResource with it. The only part I can think of that I might not have explicitly declared was the NetLoader type for the VideoElement that I can creating from the dynamic resource object.

                                • 13. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                                  nweber_dp Level 1

                                  There are many things that happen when the DynamicStreamingResource is constructed by the various loaders built in to OSMF.  This is most likely why the ABR doesn't work.  I think you should try to construct an f4m dynamically via ActionScript and pass it along with the StreamingXMLResource.

                                  • 14. Re: OSMF Bitrate Autoswitching for DynamicStreamingResource doesn't work
                                    Digiflare Level 1

                                    Yeah, that sounds like a good idea.