/// <summary>
        /// Starts the UPnP server.
        /// </summary>
        public static void Start()
        {
            if (IsRunning)
            {
                Log.Info("An UPnP/DLNA server start was requested, but it is already running.");
                Stop();
            }

            if (!Signature.IsActivated)
            {
                Log.Error("An UPnP/DLNA server start was requested, but the software is not activated.");
                return;
            }

            Log.Info("Starting UPnP/DLNA server...");

            _ms = new MediaServerDevice(_di, null, true, "http-get:*:*:*", "");
            _dw = new UPnPDeviceWatcher(_ms._Device);

            var dv = _ms.GetUPnPDevice();

            if (_favicon == null)
            {
                _favicon = new Icon(Application.GetResourceStream(new Uri("pack://application:,,,/RSTVShowTracker;component/tv.ico")).Stream);
                _icon    = new Bitmap(Application.GetResourceStream(new Uri("pack://application:,,,/RSTVShowTracker;component/Images/tv48.png")).Stream);
                _icon2   = new Bitmap(Application.GetResourceStream(new Uri("pack://application:,,,/RSTVShowTracker;component/Images/tv64.png")).Stream);
            }

            dv.favicon = _favicon;
            dv.Icon    = _icon;
            dv.Icon2   = _icon2;

            _ms.Start();

            IsRunning = true;

            _mimes = new HashSet<string>();

            RebuildList();
        }
        public MediaServerCore(string friendlyName)
        {
            if (serverCore != null) throw new Exception("Only a single MediaServerCode instance is allowed");
            serverCore = this;

            OpenSource.Utilities.EventLogger.SetLog("Media Server", "MediaServerCode", System.Windows.Forms.Application.ProductVersion.ToString());

            DeviceInfo info = new DeviceInfo();
            info.AllowRemoteContentManagement = true;
            info.FriendlyName = friendlyName;
            info.Manufacturer = "OpenSource";
            info.ManufacturerURL = "";
            info.ModelName = "Media Server";
            info.ModelDescription = "Provides content through UPnP ContentDirectory service";
            info.ModelURL = "";
            info.ModelNumber = "0.765";
            info.LocalRootDirectory = "";
            Tags T = Tags.GetInstance();
            info.SearchCapabilities = "dc:title,dc:creator,upnp:class,upnp:album,res@protocolInfo,res@size,res@bitrate";
            info.SortCapabilities = "dc:title,dc:creator,upnp:class,upnp:album";
            info.EnableSearch = true;
            info.CacheTime = MediaServerCore.CacheTime;
            info.CustomUDN = MediaServerCore.CustomUDN;
            info.INMPR03 = MediaServerCore.INMPR;

            // encode in UTF16 instead of UTF8
            MediaObject.ENCODE_UTF8 = false;

            mediaServer = new MediaServerDevice(info, null, true, "http-get:*:*:*", "");
            mediaServer.OnStatsChanged += new MediaServerDevice.Delegate_MediaServerHandler(StatsChangedChangedSink);
            mediaServer.OnHttpTransfersChanged += new MediaServerDevice.Delegate_MediaServerHandler(HttpTransfersChangedSink);
            mediaServer.OnFileNotMapped = new MediaServerDevice.Delegate_FileNotMappedHandler(this.Handle_OnRequestUnmappedFile);
            mediaServer.OnRequestAddBranch = new MediaServerDevice.Delegate_AddBranch(this.Handle_OnRequestAddBranch);
            mediaServer.OnRequestRemoveBranch = new MediaServerDevice.Delegate_RemoveBranch(this.Handle_OnRequestRemoveBranch);
            mediaServer.OnRequestChangeMetadata = new MediaServerDevice.Delegate_ChangeMetadata(this.Handle_OnRequestChangeMetadata);
            mediaServer.OnRequestSaveBinary = new MediaServerDevice.Delegate_ModifyBinary (this.Handle_OnRequestSaveBinary);
            mediaServer.OnRequestDeleteBinary = new MediaServerDevice.Delegate_ModifyBinary(this.Handle_OnRequestDeleteBinary);

            this.ResetCoreRoot();

            this.m_DeviceWatcher = new UPnPDeviceWatcher(mediaServer._Device);
            this.m_DeviceWatcher.OnSniff += new OpenSource.UPnP.UPnPDeviceWatcher.SniffHandler(this.Sink_DeviceWatcherSniff);

            this.mediaServer.Start();
            m_Paused = false;
        }
 public void StatsChangedChangedSink(MediaServerDevice sender)
 {
     if (OnStatsChanged != null) OnStatsChanged(this);
 }
 public void HttpTransfersChangedSink(MediaServerDevice sender)
 {
     if (OnHttpTransfersChanged != null) OnHttpTransfersChanged(this);
 }
 public void Dispose()
 {
     rootContainer = null;
     mediaServer.Dispose();
     mediaServer = null;
     serverCore = null;
     this.m_DeviceWatcher = null;
     this.m_DeviceWatcher.OnSniff -= new OpenSource.UPnP.UPnPDeviceWatcher.SniffHandler(this.Sink_DeviceWatcherSniff);
 }
        private void Handle_OnRequestUnmappedFile(MediaServerDevice sender, MediaServerDevice.FileNotMapped getPacket)
        {
            string path_query = getPacket.RequestedResource.ContentUri.Substring(DvMediaResource.AUTOMAPFILE.Length);

            DText path_queryParser = new DText();

            if (getPacket.RequestedResource.Owner.Class.IsA(MediaBuilder.StandardMediaClasses.ImageItem))
            {
                path_queryParser.ATTRMARK = "?";
                path_queryParser.MULTMARK = "=";
                path_queryParser.SUBVMARK = ",";
                path_queryParser[0] = path_query;

                string path = path_queryParser[1];
                string query = path_queryParser[2];
                string format = path_queryParser[2,1];
                string resolution = path_queryParser[2,2];

                string resX = path_queryParser[2,2,1];
                string resY = path_queryParser[2,2,2];

                int width = int.Parse(resX);
                int height = int.Parse(resY);
                int max = Math.Max(width, height);

                Image image = Image.FromFile(path);
                Image thumbnail = image.GetThumbnailImage(width, height, null, IntPtr.Zero);

                getPacket.RedirectedStream = new MemoryStream();
                thumbnail.Save(getPacket.RedirectedStream, ImageFormat.Jpeg);
            }
            else if (
                (getPacket.RequestedResource.Owner.Class.IsA(MediaBuilder.StandardMediaClasses.PlaylistContainer)) ||
                (getPacket.RequestedResource.Owner.Class.IsA(MediaBuilder.StandardMediaClasses.PlaylistItem))
                )
            {
                path_queryParser.ATTRMARK = "?";
                path_queryParser.MULTMARK = "=";
                path_queryParser[0] = path_query;

                string path = path_queryParser[1];
                string query = path_queryParser[2];
                string format = path_queryParser[2,1];
                string baseUrl = getPacket.LocalInterface;

                FileInfo fi = (FileInfo) ((DvMediaResource) getPacket.RequestedResource).Tag;

                //TODO: build m3u
                MemoryStream m3u = new MemoryStream((int)fi.Length * 5);
                StreamWriter sw = new StreamWriter(m3u, System.Text.Encoding.UTF8);
                getPacket.RedirectedStream = m3u;

                sw.Write("\n");
                sw.Flush();
                m3u.Position = 0;

                DvMediaContainer dvc = (DvMediaContainer) getPacket.RequestedResource.Owner;

                sw.WriteLine("#EXTM3U");
                foreach (DvMediaItem dvi in dvc.CompleteList)
                {
                    StringBuilder extInfo = new StringBuilder(dvi.Title.Length + dvi.Creator.Length + 15);
                    StringBuilder uri = new StringBuilder(1024);

                    //digital home looks for a single '-' to delimit creator/title
                    extInfo.AppendFormat("#EXTINF:-1,{0} - {1}", dvi.Creator.Replace("-", "_"), dvi.Title.Replace("-", "_"));
                    sw.WriteLine(extInfo.ToString());

                    IList resources = dvi.MergedResources;
                    DvMediaResource res = resources[0] as DvMediaResource;
                    if (res != null)
                    {
                        if (res.ContentUri.StartsWith(MediaResource.AUTOMAPFILE))
                        {
                            uri.AppendFormat("http://{0}/{1}{2}", baseUrl, mediaServer.VirtualDirName, res.RelativeContentUri);
                        }
                        else
                        {
                            uri.Append(res.ContentUri);
                        }

                        sw.WriteLine(uri);
                    }
                    else
                    {
                        StringBuilder msg = new StringBuilder();
                        if (resources.Count == 0)
                        {
                            msg.AppendFormat("MediaServerCore.Handle_OnRequestUnmappedFile() encountered a media object ID=\"{0}\" Title=\"{1}\" with zero resources.", dvi.ID, dvi.Title);
                        }
                        else
                        {
                            msg.AppendFormat("MediaServerCore.Handle_OnRequestUnmappedFile() encountered a media object ID=\"{0}\" Title=\"{1}\" with resource that is not a DvMediaResource.", dvi.ID, dvi.Title);
                        }
                        OpenSource.Utilities.EventLogger.Log(msg.ToString());
                    }
                }

                sw.Flush();
            }
        }
 private void Handle_OnRequestSaveBinary(MediaServerDevice sender, IDvResource res)
 {
     Exception error = null;
     this.m_LockRoot.WaitOne();
     try
     {// Throw exceptions if files are to not be deleted.
         //
         if (res.AllowImport == false)
         {
             throw new Error_AccessDenied("The resource cannot be overwritten or created.");
         }
     }
     catch (Exception e)
     {
         error = e;
     }
     this.m_LockRoot.ReleaseMutex();
     if (error != null)
     {
         throw new ApplicationException("Handle_OnRequestSaveBinary()", error);
     }
 }
 private void Handle_OnRequestRemoveBranch(MediaServerDevice sender, DvMediaContainer parentContainer, IDvMedia removeThisBranch)
 {
     Exception error = null;
     this.m_LockRoot.WaitOne();
     try
     {
         parentContainer.RemoveBranch(removeThisBranch);
     }
     catch (Exception e)
     {
         error = e;
     }
     this.m_LockRoot.ReleaseMutex();
     if (error != null)
     {
         throw new ApplicationException("Handle_OnRequestRemoveBranch()", error);
     }
 }
        private void Handle_OnRequestDeleteBinary(MediaServerDevice sender, IDvResource res)
        {
            Exception error = null;
            this.m_LockRoot.WaitOne();
            try
            {

                // Throw exceptions if the file should not be deleted.
                //
                if (res.AllowImport == false)
                {
                    //throw new Error_AccessDenied("The resource cannot be deleted.");
                }

                /// The UPNP layer will not delete the actual file from the local file system.
                /// I should note that if multiple resources are bound to the same file, then
                /// the logic in this method prevents the file from being deleted.
                ///
                if (res.ContentUri.StartsWith(DvMediaResource.AUTOMAPFILE))
                {
                    string filename = res.ContentUri.Substring(DvMediaResource.AUTOMAPFILE.Length);
                    File.Delete(filename);
                }
            }
            catch (Exception e)
            {
                error = e;
            }
            this.m_LockRoot.ReleaseMutex();
            if (error != null)
            {
                throw new ApplicationException("Handle_OnRequestDeleteBinary()", error);
            }
        }
        private void Handle_OnRequestChangeMetadata(MediaServerDevice sender, IDvMedia oldObject, IDvMedia newObject)
        {
            Exception error = null;
            this.m_LockRoot.WaitOne();

            try
            {

                /// TODO: Add permissions logic
                ///
                /// The following metadata fields must be the same between the old and new objects.
                ///		ID,
                ///		refID
                ///		Parent
                ///		IsRestricted
                ///
                if (oldObject.IsRestricted)
                {
                    //Allow everything for now
                    //throw new Error_RestrictedObject("Cannot modify a restricted object.");
                }

                if (oldObject.ID != newObject.ID)
                {
                    throw new Error_ReadOnlyTag("Cannot modify ID");
                }

                if (oldObject.IsContainer != newObject.IsContainer)
                {
                    throw new Error_BadMetadata("Cannot change containers into items.");
                }

                if (oldObject.IsItem != newObject.IsItem)
                {
                    throw new Error_BadMetadata("Cannot change items into containers.");
                }

                if (oldObject.IsRestricted != newObject.IsRestricted)
                {
                    throw new Error_ReadOnlyTag("Cannot change the \"restricted\" attribute.");
                }

                if ((oldObject.IsReference) || (newObject.IsReference))
                {
                    if (oldObject.IsReference == newObject.IsReference)
                    {
                        DvMediaItem oldItem = (DvMediaItem) oldObject;
                        DvMediaItem newItem = (DvMediaItem) newObject;

                        string refid1 = oldItem.RefID;
                        string refid2 = newItem.RefID;

                        if (string.Compare(refid1, refid2) != 0)
                        {
                            throw new Error_ReadOnlyTag("Cannot change the \"refID\" attribute.");
                        }
                    }
                    else
                    {
                        throw new Error_BadMetadata("Cannot change a reference item into a non-reference.");
                    }
                }
            }
            catch (Exception e)
            {
                error = e;
            }
            this.m_LockRoot.ReleaseMutex();
            if (error != null)
            {
                throw new ApplicationException("Handle_OnRequestChangeMetadata()", error);
            }

            // TODO: Actually check validity for metadata of media objects and their resources.
        }
        private void Handle_OnRequestAddBranch(MediaServerDevice sender, DvMediaContainer parentContainer, ref IDvMedia[] addTheseBranches)
        {
            Exception error = null;
            this.m_LockRoot.WaitOne();

            try
            {
                if (parentContainer == this.mediaServer.Root)
                {
                    throw new Error_RestrictedObject("Cannot create objects directly in the root container.");
                }
                else if (parentContainer.IsRestricted)
                {
                    throw new Error_RestrictedObject("Cannot create objects in a restricted container.");
                }

                InnerMediaDirectory mediadir = (InnerMediaDirectory) parentContainer.Tag;
                bool allowNewLocalResources = true;
                if (mediadir != null)
                {
                    allowNewLocalResources = Directory.Exists(mediadir.directory.FullName);
                }
                foreach (IDvMedia branch in addTheseBranches)
                {
                    // Throw an exception if ANYTHING is bad. Add is always
                    // atomic per request.
                    //
                    ValidateBranch(parentContainer, branch, allowNewLocalResources);
                }

                foreach (IDvMedia branch in addTheseBranches)
                {
                    // No exceptions were thrown so go ahead and add new
                    // files and directories to the local file system
                    // for the new tree.
                    //
                    if (branch.IsReference == true)
                    {
                        parentContainer.AddBranch(branch);
                    }
                    else
                    {
                        ModifyLocalFileSystem(parentContainer, branch);
                    }
                }
            }
            catch (Exception e)
            {
                error = e;
            }
            this.m_LockRoot.ReleaseMutex();

            if (error != null)
            {
                throw new ApplicationException("Handle_OnRequestAddBranch()", error);
            }
        }
 /// <summary>
 /// Indicates vendor-specific error code of 881.
 /// </summary>
 /// <param name="id"></param>
 /// <param name="transferInfo"></param>
 public Error_TransferProblem(UInt32 id, MediaServerDevice.HttpTransfer transferInfo)
     : base(881, "Error with transfer " + id.ToString())
 {
     TransferId = id;
     TransferInfo = transferInfo;
 }
Example #13
0
        /// <summary>
        /// Stops the UPnP server.
        /// </summary>
        public static void Stop()
        {
            Log.Info("Stopping UPnP/DLNA server...");

            IsRunning = false;

            _ms.Stop();
            _ms.Dispose();
            _ms = null;
            _dw = null;
        }