Пример #1
0
        public IEnumerable <Issue> GetIssue(BeatmapSet beatmapSet, string audioPath, bool isHitSound = false)
        {
            // `Audio.GetBitrate` has a < 0.1 kbps error margin, so we should round this.
            double bitrate = Math.Round(AudioBASS.GetBitrate(audioPath));

            // Hit sounds only need to follow the lower limit for quality requirements, as Wave
            // (which is the most used hit sound format currently) is otherwise uncompressed anyway.
            if (bitrate >= 128 && (bitrate <= 192 || isHitSound))
            {
                yield break;
            }

            string audioRelPath = PathStatic.RelativePath(audioPath, beatmapSet.songPath);

            if (!isHitSound)
            {
                yield return(new Issue(GetTemplate("Bitrate"), null,
                                       audioRelPath, $"{bitrate:0.##}",
                                       (bitrate < 128 ? "low" : "high")));
            }
            else
            {
                yield return(new Issue(GetTemplate("Hit Sound"), null,
                                       audioRelPath, $"{bitrate:0.##}"));
            }
        }
Пример #2
0
        private static string RenderResources(BeatmapSet aBeatmapSet)
        {
            string RenderFloat(List <string> aFiles, Func <string, string> aFunc)
            {
                string content =
                    String.Join("<br>",
                                aFiles.Select(aFile =>
                {
                    string path =
                        aBeatmapSet.hitSoundFiles.FirstOrDefault(anOtherFile =>
                                                                 anOtherFile.StartsWith(aFile + "."));
                    if (path == null)
                    {
                        return(null);
                    }

                    return(aFunc(path));
                }).Where(aValue => aValue != null)
                                );

                if (content.Length == 0)
                {
                    return("");
                }

                return(Div("overview-float", content));
            }

            Dictionary <string, int> hsUsedCount = new Dictionary <string, int>();

            return
                (RenderContainer("Resources",
                                 RenderBeatmapContent(aBeatmapSet, "Used Hit Sound File(s)", aBeatmap =>
            {
                List <string> usedHitSoundFiles =
                    aBeatmap.hitObjects.SelectMany(anObject => anObject.GetUsedHitSoundFileNames()).ToList();

                List <string> distinctSortedFiles =
                    usedHitSoundFiles.Distinct().OrderByDescending(aFile => aFile).ToList();

                return
                RenderFloat(distinctSortedFiles, aPath => Encode(aPath)) +
                RenderFloat(distinctSortedFiles, aPath =>
                {
                    int count = usedHitSoundFiles.Where(anOtherFile => aPath.StartsWith(anOtherFile + ".")).Count();

                    // Used for total hit sound usage overview
                    if (hsUsedCount.ContainsKey(aPath))
                    {
                        hsUsedCount[aPath] += count;
                    }
                    else
                    {
                        hsUsedCount[aPath] = count;
                    }

                    return $"× {count}";
                });
            }, false),
                                 RenderField("Total Used Hit Sound File(s)",
                                             (hsUsedCount.Any() ?
                                              Div("overview-float",
                                                  String.Join("<br>",
                                                              hsUsedCount.Select(aPair => aPair.Key)
                                                              )
                                                  ) +
                                              Div("overview-float",
                                                  String.Join("<br>",
                                                              hsUsedCount.Select(aPair =>
                                                                                 Try(() =>
            {
                string fullPath = Path.Combine(aBeatmapSet.songPath, aPair.Key);

                return Encode(RenderFileSize(fullPath));
            },
                                                                                     noteIfError: "Could not get hit sound file size"
                                                                                     )
                                                                                 )
                                                              )
                                                  ) +
                                              Div("overview-float",
                                                  String.Join("<br>",
                                                              hsUsedCount.Select(aPair =>
                                                                                 Try(() =>
            {
                string fullPath = Path.Combine(aBeatmapSet.songPath, aPair.Key);
                double duration = AudioBASS.GetDuration(fullPath);

                if (duration < 0)
                {
                    return "0 ms";
                }

                return $"{duration:0.##} ms";
            },
                                                                                     noteIfError: "Could not get hit sound duration"
                                                                                     )
                                                                                 )
                                                              )
                                                  ) +
                                              Div("overview-float",
                                                  String.Join("<br>",
                                                              hsUsedCount.Select(aPair =>
                                                                                 Try(() =>
            {
                string fullPath = Path.Combine(aBeatmapSet.songPath, aPair.Key);

                return Encode(AudioBASS.EnumToString(AudioBASS.GetFormat(fullPath)));
            },
                                                                                     noteIfError: "Could not get hit sound file path"
                                                                                     )
                                                                                 )
                                                              )
                                                  ) +
                                              Div("overview-float",
                                                  String.Join("<br>",
                                                              hsUsedCount.Select(aPair => "× " + aPair.Value)
                                                              )
                                                  )
                        : "")
                                             ),
                                 RenderBeatmapContent(aBeatmapSet, "Background File(s)", aBeatmap =>
            {
                if (aBeatmap.backgrounds.Any())
                {
                    string fullPath = Path.Combine(aBeatmap.songPath, aBeatmap.backgrounds.First().path);
                    if (!File.Exists(fullPath))
                    {
                        return "";
                    }

                    string error = null;
                    TagLib.File tagFile = null;
                    try
                    { tagFile = new FileAbstraction(fullPath).GetTagFile(); }
                    catch (Exception exception)
                    {
                        error = exception.Message;
                    }

                    return
                    Div("overview-float",
                        Try(() =>
                            Encode(aBeatmap.backgrounds.First().path),
                            noteIfError: "Could not get background file path"
                            )
                        ) +
                    Div("overview-float",
                        Try(() =>
                            Encode(RenderFileSize(fullPath)),
                            noteIfError: "Could not get background file size"
                            )
                        ) +
                    ((error != null || tagFile == null) ?
                     Div("overview-float",
                         Try(() =>
                             Encode(tagFile.Properties.PhotoWidth + " x " + tagFile.Properties.PhotoHeight),
                             noteIfError: "Could not get background resolution"
                             )
                         ) :
                     Div("overview-float",
                         Encode($"(failed getting proprties; {error})")
                         ));
                }
                else
                {
                    return "";
                }
            }, false),
                                 RenderBeatmapContent(aBeatmapSet, "Video File(s)", aBeatmap =>
            {
                if (aBeatmap.videos.Any() || (aBeatmapSet.osb?.videos.Any() ?? false))
                {
                    string fullPath = Path.Combine(aBeatmap.songPath, aBeatmap.videos.First().path);
                    if (!File.Exists(fullPath))
                    {
                        return "";
                    }

                    string error = null;
                    TagLib.File tagFile = null;
                    try
                    { tagFile = new FileAbstraction(fullPath).GetTagFile(); }
                    catch (Exception exception)
                    { error = exception.Message; }

                    return
                    Div("overview-float",
                        Try(() =>
                            Encode(aBeatmap.videos.First().path),
                            noteIfError: "Could not get video file path"
                            )
                        ) +
                    Div("overview-float",
                        Try(() =>
                            Encode(RenderFileSize(fullPath)),
                            noteIfError: "Could not get video file size"
                            )
                        ) +
                    ((error != null || tagFile == null) ?
                     Div("overview-float",
                         Try(() =>
                             FormatTimestamps(Encode(Timestamp.Get(tagFile.Properties.Duration.TotalMilliseconds))),
                             noteIfError: "Could not get video duration"
                             )
                         ) +
                     Div("overview-float",
                         Try(() =>
                             Encode(tagFile.Properties.VideoWidth + " x " + tagFile.Properties.VideoHeight),
                             noteIfError: "Could not get video resolution"
                             )
                         ) :
                     Div("overview-float",
                         Encode($"(failed getting proprties; {error})")
                         ));
                }
                else
                {
                    return "";
                }
            }, false),
                                 RenderBeatmapContent(aBeatmapSet, "Audio File(s)", aBeatmap =>
            {
                string path = aBeatmap.GetAudioFilePath();
                if (path == null)
                {
                    return "";
                }

                return
                Div("overview-float",
                    Try(() =>
                        Encode(PathStatic.RelativePath(path, aBeatmap.songPath)),
                        noteIfError: "Could not get audio file path"
                        )
                    ) +
                Div("overview-float",
                    Try(() =>
                        Encode(RenderFileSize(path)),
                        noteIfError: "Could not get audio file size"
                        )
                    ) +
                Div("overview-float",
                    Try(() =>
                        FormatTimestamps(Encode(Timestamp.Get(AudioBASS.GetDuration(path)))),
                        noteIfError: "Could not get audio duration"
                        )
                    ) +
                Div("overview-float",
                    Try(() =>
                        Encode(AudioBASS.EnumToString(AudioBASS.GetFormat(path))),
                        noteIfError: "Could not get audio format"
                        )
                    );
            }, false),
                                 RenderBeatmapContent(aBeatmapSet, "Audio Bitrate", aBeatmap =>
            {
                string path = aBeatmap.GetAudioFilePath();
                if (path == null)
                {
                    return "N/A";
                }

                return
                Div("overview-float",
                    $"average {Math.Round(AudioBASS.GetBitrate(path))} kbps"
                    );
            }, false),
                                 RenderField("Has .osb",
                                             Encode((aBeatmapSet.osb?.IsUsed() ?? false).ToString())
                                             ),
                                 RenderBeatmapContent(aBeatmapSet, "Has .osu Specific Storyboard", aBeatmap =>
                                                      aBeatmap.HasDifficultySpecificStoryboard().ToString()),
                                 RenderBeatmapContent(aBeatmapSet, "Song Folder Size", aBeatmap =>
                                                      RenderDirectorySize(aBeatmap.songPath))
                                 ));
        }