Exemple #1
0
        public static void FillVideoInfoFromMedia(VideoLocal info, Media m)
        {
            info.VideoResolution = (!string.IsNullOrEmpty(m.Width) && !string.IsNullOrEmpty(m.Height))
                      ? m.Width + "x" + m.Height
                      : string.Empty;
            info.VideoCodec = (!string.IsNullOrEmpty(m.VideoCodec)) ? m.VideoCodec : string.Empty;
            info.AudioCodec = (!string.IsNullOrEmpty(m.AudioCodec)) ? m.AudioCodec : string.Empty;


            if (!string.IsNullOrEmpty(m.Duration))
            {
                double duration;
                bool   isValidDuration = double.TryParse(m.Duration, out duration);
                if (isValidDuration)
                {
                    info.Duration =
                        (long)double.Parse(m.Duration, NumberStyles.Any, CultureInfo.InvariantCulture);
                }
                else
                {
                    info.Duration = 0;
                }
            }
            else
            {
                info.Duration = 0;
            }

            info.VideoBitrate = info.VideoBitDepth = info.VideoFrameRate = info.AudioBitrate = string.Empty;
            List <JMMContracts.PlexAndKodi.Stream> vparts = m.Parts[0].Streams.Where(a => a.StreamType == "1").ToList();

            if (vparts.Count > 0)
            {
                if (!string.IsNullOrEmpty(vparts[0].Bitrate))
                {
                    info.VideoBitrate = vparts[0].Bitrate;
                }
                if (!string.IsNullOrEmpty(vparts[0].BitDepth))
                {
                    info.VideoBitDepth = vparts[0].BitDepth;
                }
                if (!string.IsNullOrEmpty(vparts[0].FrameRate))
                {
                    info.VideoFrameRate = vparts[0].FrameRate;
                }
            }
            List <JMMContracts.PlexAndKodi.Stream> aparts = m.Parts[0].Streams.Where(a => a.StreamType == "2").ToList();

            if (aparts.Count > 0)
            {
                if (!string.IsNullOrEmpty(aparts[0].Bitrate))
                {
                    info.AudioBitrate = aparts[0].Bitrate;
                }
            }
        }
        public static void FillVideoInfoFromMedia(VideoLocal info, Media m)
        {
            info.VideoResolution = (!string.IsNullOrEmpty(m.Width) && !string.IsNullOrEmpty(m.Height))
                      ? m.Width + "x" + m.Height
                      : string.Empty;
            info.VideoCodec = (!string.IsNullOrEmpty(m.VideoCodec)) ? m.VideoCodec : string.Empty;
            info.AudioCodec = (!string.IsNullOrEmpty(m.AudioCodec)) ? m.AudioCodec : string.Empty;

            if (!string.IsNullOrEmpty(m.Duration))
            {
                double duration;
                bool isValidDuration = double.TryParse(m.Duration, out duration);
                if (isValidDuration)
                    info.Duration =
                        (long)double.Parse(m.Duration, NumberStyles.Any, CultureInfo.InvariantCulture);
                else
                    info.Duration = 0;
            }
            else
                info.Duration = 0;

            info.VideoBitrate = info.VideoBitDepth = info.VideoFrameRate = info.AudioBitrate = string.Empty;
            List<JMMContracts.PlexAndKodi.Stream> vparts = m.Parts[0].Streams.Where(a => a.StreamType == "1").ToList();
            if (vparts.Count > 0)
            {
                if (!string.IsNullOrEmpty(vparts[0].Bitrate))
                    info.VideoBitrate = vparts[0].Bitrate;
                if (!string.IsNullOrEmpty(vparts[0].BitDepth))
                    info.VideoBitDepth = vparts[0].BitDepth;
                if (!string.IsNullOrEmpty(vparts[0].FrameRate))
                    info.VideoFrameRate = vparts[0].FrameRate;
            }
            List<JMMContracts.PlexAndKodi.Stream> aparts = m.Parts[0].Streams.Where(a => a.StreamType == "2").ToList();
            if (aparts.Count > 0)
            {
                if (!string.IsNullOrEmpty(aparts[0].Bitrate))
                    info.AudioBitrate = aparts[0].Bitrate;
            }
        }
        public static Media Convert(string filename, IFile file)
        {
            if (file == null)
                return null;
            try
            {
                lock (_lock)
                {
                    Media m = new Media();
                    Part p = new Part();
                    Thread mediaInfoThread = new Thread(() =>
                    {
                        if (minstance==null)
                            minstance=new MediaInfoLib.MediaInfo();
                        minstance.Open(filename);
                        Stream VideoStream = null;
                        int video_count = minstance.GetInt(StreamKind.General, 0, "VideoCount");
                        int audio_count = minstance.GetInt(StreamKind.General, 0, "AudioCount");
                        int text_count = minstance.GetInt(StreamKind.General, 0, "TextCount");
                        m.Duration = p.Duration = minstance.Get(StreamKind.General, 0, "Duration");
                        m.Container = p.Container = TranslateContainer(minstance.Get(StreamKind.General, 0, "Format"));
                        string codid = minstance.Get(StreamKind.General, 0, "CodecID");
                        if (!string.IsNullOrEmpty(codid) && (codid.Trim().ToLower() == "qt"))
                            m.Container = p.Container = "mov";

                        int brate = minstance.GetInt(StreamKind.General, 0, "BitRate");
                        if (brate != 0)
                            m.Bitrate = Math.Round(brate / 1000F).ToString(CultureInfo.InvariantCulture);
                        p.Size = minstance.Get(StreamKind.General, 0, "FileSize");
                        List<Stream> streams = new List<Stream>();
                        int iidx = 0;
                        if (video_count > 0)
                        {
                            for (int x = 0; x < video_count; x++)
                            {
                                Stream s = TranslateVideoStream(minstance, x);
                                if (x == 0)
                                {
                                    VideoStream = s;
                                    m.Width = s.Width;
                                    m.Height = s.Height;
                                    if (!string.IsNullOrEmpty(m.Height))
                                    {
                                        if (!string.IsNullOrEmpty(m.Width))
                                        {
                                            m.VideoResolution = GetResolution(float.Parse(m.Width), float.Parse(m.Height));
                                            m.AspectRatio = GetAspectRatio(float.Parse(m.Width), float.Parse(m.Height), s.PA);
                                        }
                                    }
                                    if (!string.IsNullOrEmpty(s.FrameRate))
                                    {
                                        float fr = System.Convert.ToSingle(s.FrameRate);
                                        m.VideoFrameRate = ((int)Math.Round(fr)).ToString(CultureInfo.InvariantCulture);
                                        if (!string.IsNullOrEmpty(s.ScanType))
                                        {
                                            if (s.ScanType.ToLower().Contains("int"))
                                                m.VideoFrameRate += "i";
                                            else
                                                m.VideoFrameRate += "p";
                                        }
                                        else
                                            m.VideoFrameRate += "p";
                                        if ((m.VideoFrameRate == "25p") || (m.VideoFrameRate == "25i"))
                                            m.VideoFrameRate = "PAL";
                                        else if ((m.VideoFrameRate == "30p") || (m.VideoFrameRate == "30i"))
                                            m.VideoFrameRate = "NTSC";
                                    }
                                    m.VideoCodec = s.Codec;
                                    if (!string.IsNullOrEmpty(m.Duration) && !string.IsNullOrEmpty(s.Duration))
                                    {
                                        double sdur = 0;
                                        double mdur = 0;
                                        double.TryParse(s.Duration, NumberStyles.Any, CultureInfo.InvariantCulture, out sdur);
                                        double.TryParse(m.Duration, NumberStyles.Any, CultureInfo.InvariantCulture, out mdur);
                                        if (sdur > mdur)
                                            m.Duration = p.Duration = ((int)sdur).ToString();
                                    }
                                    if (video_count == 1)
                                    {
                                        s.Default = null;
                                        s.Forced = null;
                                    }
                                }

                                if (m.Container != "mkv")
                                {
                                    s.Index = iidx.ToString(CultureInfo.InvariantCulture);
                                    iidx++;
                                }
                                streams.Add(s);
                            }
                        }
                        int totalsoundrate = 0;
                        if (audio_count > 0)
                        {
                            for (int x = 0; x < audio_count; x++)
                            {
                                Stream s = TranslateAudioStream(minstance, x);
                                if ((s.Codec == "adpcm") && (p.Container == "flv"))
                                    s.Codec = "adpcm_swf";
                                if (x == 0)
                                {
                                    m.AudioCodec = s.Codec;
                                    m.AudioChannels = s.Channels;
                                    if (!string.IsNullOrEmpty(m.Duration) && !string.IsNullOrEmpty(s.Duration))
                                    {
                                        double sdur = 0;
                                        double mdur = 0;
                                        double.TryParse(s.Duration, NumberStyles.Any, CultureInfo.InvariantCulture, out sdur);
                                        double.TryParse(m.Duration, NumberStyles.Any, CultureInfo.InvariantCulture, out mdur);
                                        if (sdur > mdur)
                                            m.Duration = p.Duration = ((int)sdur).ToString();
                                    }
                                    if (audio_count == 1)
                                    {
                                        s.Default = null;
                                        s.Forced = null;
                                    }
                                }
                                if (!string.IsNullOrEmpty(s.Bitrate))
                                {
                                    double birate = 0;
                                    double.TryParse(s.Bitrate, NumberStyles.Any, CultureInfo.InvariantCulture, out birate);
                                    totalsoundrate += (int)brate;
                                }
                                if (m.Container != "mkv")
                                {
                                    s.Index = iidx.ToString(CultureInfo.InvariantCulture);
                                    iidx++;
                                }
                                streams.Add(s);
                            }
                        }
                        if ((VideoStream != null) && string.IsNullOrEmpty(VideoStream.Bitrate) &&
                            !string.IsNullOrEmpty(m.Bitrate))
                        {
                            double mrate = 0;
                            double.TryParse(m.Bitrate, NumberStyles.Any, CultureInfo.InvariantCulture, out mrate);
                            VideoStream.Bitrate = (((int)mrate) - totalsoundrate).ToString(CultureInfo.InvariantCulture);
                        }
                        if (text_count > 0)
                        {
                            for (int x = 0; x < audio_count; x++)
                            {
                                Stream s = TranslateTextStream(minstance, x);
                                streams.Add(s);
                                if (text_count == 1)
                                {
                                    s.Default = null;
                                    s.Forced = null;
                                }
                                if (m.Container != "mkv")
                                {
                                    s.Index = iidx.ToString(CultureInfo.InvariantCulture);
                                    iidx++;
                                }
                            }
                        }
                        m.Parts = new List<Part>();
                        m.Parts.Add(p);
                        bool over = false;
                        if (m.Container == "mkv")
                        {
                            int val = int.MaxValue;
                            foreach (Stream s in streams)
                            {
                                if (string.IsNullOrEmpty(s.Index))
                                {
                                    over = true;
                                    break;
                                }
                                s.idx = int.Parse(s.Index);
                                if (s.idx < val)
                                    val = s.idx;
                            }
                            if ((val != 0) && !over)
                            {
                                foreach (Stream s in streams)
                                {
                                    s.idx = s.idx - val;
                                    s.Index = s.idx.ToString(CultureInfo.InvariantCulture);
                                }
                            }
                            else if (over)
                            {
                                int xx = 0;
                                foreach (Stream s in streams)
                                {
                                    s.idx = xx++;
                                    s.Index = s.idx.ToString(CultureInfo.InvariantCulture);
                                }
                            }
                            streams = streams.OrderBy(a => a.idx).ToList();
                        }
                        p.Streams = streams;
                    });
                    mediaInfoThread.Start();
                    bool finished = mediaInfoThread.Join(TimeSpan.FromMinutes(5)); //TODO Move Timeout to settings
                    if (!finished)
                    {
                        try { mediaInfoThread.Abort();} catch {  /*ignored*/ }
                        try { CloseMediaInfo(); } catch { /*ignored*/}
                        return null;
                    }
                    if ((p.Container == "mp4") || (p.Container == "mov"))
                    {
                        p.Has64bitOffsets = "0";
                        p.OptimizedForStreaming = "0";
                        m.OptimizedForStreaming = "0";
                        byte[] buffer = new byte[8];
                        FileSystemResult<System.IO.Stream> fsr = file.OpenRead();
                        if (!fsr.IsOk)
                            return null;
                        System.IO.Stream fs = fsr.Result;
                        fs.Read(buffer, 0, 4);
                        int siz = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
                        fs.Seek(siz, SeekOrigin.Begin);
                        fs.Read(buffer, 0, 8);
                        if ((buffer[4] == 'f') && (buffer[5] == 'r') && (buffer[6] == 'e') && (buffer[7] == 'e'))
                        {
                            siz = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3] - 8;
                            fs.Seek(siz, SeekOrigin.Current);
                            fs.Read(buffer, 0, 8);
                        }
                        if ((buffer[4] == 'm') && (buffer[5] == 'o') && (buffer[6] == 'o') && (buffer[7] == 'v'))
                        {
                            p.OptimizedForStreaming = "1";
                            m.OptimizedForStreaming = "1";
                            siz = (buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]) - 8;

                            buffer = new byte[siz];
                            fs.Read(buffer, 0, siz);
                            int opos;
                            int oposmax;
                            if (FindInBuffer("trak", 0, siz, buffer, out opos, out oposmax))
                            {
                                if (FindInBuffer("mdia", opos, oposmax, buffer, out opos, out oposmax))
                                {
                                    if (FindInBuffer("minf", opos, oposmax, buffer, out opos, out oposmax))
                                    {
                                        if (FindInBuffer("stbl", opos, oposmax, buffer, out opos, out oposmax))
                                        {
                                            if (FindInBuffer("co64", opos, oposmax, buffer, out opos, out oposmax))
                                            {
                                                p.Has64bitOffsets = "1";
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    return m;
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.Message, e);
            }
            finally
            {
                minstance?.Close();
                GC.Collect();
            }
        }
Exemple #4
0
        public bool RefreshMediaInfo()
        {
            try
            {
                logger.Trace($"Getting media info for: {FullServerPath}");
                Media m = null;
                List <Providers.Azure.Media> webmedias = AzureWebAPI.Get_Media(VideoLocal.ED2KHash);
                if (webmedias != null && webmedias.Count > 0)
                {
                    m = webmedias[0].GetMedia();
                }
                if (m == null)
                {
                    string name = (ImportFolder.CloudID == null)
                        ? FullServerPath.Replace("/", "\\")
                        : PlexAndKodi.Helper.ReplaceSchemeHost(PlexAndKodi.Helper.ConstructVideoLocalStream(0,
                                                                                                            VideoLocalID.ToString(), "file", false));
                    m = MediaConvert.Convert(name, GetFile()); //Mediainfo should have libcurl.dll for http
                    if (string.IsNullOrEmpty(m.Duration))
                    {
                        m = null;
                    }
                    if (m != null)
                    {
                        AzureWebAPI.Send_Media(VideoLocal.ED2KHash, m);
                    }
                }


                if (m != null)
                {
                    VideoLocal info = VideoLocal;
                    FillVideoInfoFromMedia(info, m);

                    m.Id = VideoLocalID.ToString();
                    List <JMMContracts.PlexAndKodi.Stream> subs = SubtitleHelper.GetSubtitleStreams(this);
                    if (subs.Count > 0)
                    {
                        m.Parts[0].Streams.AddRange(subs);
                    }
                    foreach (Part p in m.Parts)
                    {
                        p.Id         = null;
                        p.Accessible = "1";
                        p.Exists     = "1";
                        bool vid = false;
                        bool aud = false;
                        bool txt = false;
                        foreach (JMMContracts.PlexAndKodi.Stream ss in p.Streams.ToArray())
                        {
                            if ((ss.StreamType == "1") && !vid)
                            {
                                vid = true;
                            }
                            if ((ss.StreamType == "2") && !aud)
                            {
                                aud         = true;
                                ss.Selected = "1";
                            }
                            if ((ss.StreamType == "3") && !txt)
                            {
                                txt         = true;
                                ss.Selected = "1";
                            }
                        }
                    }
                    info.Media = m;
                    return(true);
                }
                logger.Error($"File {FullServerPath} does not exist, unable to read media information from it");
            }
            catch (Exception e)
            {
                logger.Error($"Unable to read the media information of file {FullServerPath} ERROR: {e}");
            }
            return(false);
        }