tomaszzmuda / Xabe.FFmpeg

.NET Standard wrapper for FFmpeg. It allows to process media without know how FFmpeg works, and can be used to pass customized arguments to FFmpeg from dotnet core application.
https://xabe.net/product/xabe_ffmpeg/
Other
714 stars 128 forks source link

FFmpegDownloader.GetLatestVersion downloads a potentially incompatible version #394

Open Yousif-FJ opened 2 years ago

Yousif-FJ commented 2 years ago

Suppose you have this scenario: An application is in production with FFmpegDownloader.GetLatestVersion, is it possible that the FFmpeg receive a breaking update which breaks something with the main Xabe.FFmpeg package? in that case we would have an application that could break on its own in production. If this is the case, we could add an option to select the version rather than the latest version?

alizamani84 commented 2 years ago

@Yousif-FJ The scenario you described happened to us. Following line of code in our application caused below exception which led to application startup failure.

await Xabe.FFmpeg.Downloader.FFmpegDownloader.GetLatestVersion(FFmpegVersion.Official, FFMpegDownloadPath).ConfigureAwait(false);

image

@tomaszzmuda Could you please shed some light?

alizamani84 commented 2 years ago

After some investigation in the source code, it turned out issue was not about downloading the latest version but when downloaded zip file had to be unzipped. FFmpegDownloader needs to ensure destination path exists before extracting the downloaded zip file. Code below in FullFFMpegDownloader.cs could solve the issue.

var directoryPath = Path.GetDirectoryName(destinationPath); if (!Directory.Exists(directoryPath)) { Directory.CreateDirectory(directoryPath); }

A PR was created to resolve this issue. If you hurry, then download source code and use it in your project by needed modification as I explained above.

theolivenbaum commented 2 years ago

@tomaszzmuda same thing happening to us under Linux. Any chance you can get a look at it?

For us it's happening with the OfficialFFmpegDownloader as well - so the PR from @alizamani84 is not solving the whole problem.

Also, might be worth skipping the __MACOSX directory as that's not really necessary but might have been included in the zip file by mistake.

Unhandled exception. System.IO.DirectoryNotFoundException: Could not find a part of the path '/app/__MACOSX/._ffmpeg'.
   at Interop.ThrowExceptionForIoErrno(ErrorInfo errorInfo, String path, Boolean isDirectory, Func`2 errorRewriter)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync)
   at System.IO.Compression.ZipFileExtensions.ExtractToFile(ZipArchiveEntry source, String destinationFileName, Boolean overwrite)
   at Xabe.FFmpeg.Downloader.FFmpegDownloaderBase.Extract(String ffMpegZipPath, String destinationDir)
   at Xabe.FFmpeg.Downloader.OfficialFFmpegDownloader.DownloadLatestVersion(FFbinariesVersionInfo latestFFmpegBinaries, String path, IProgress`1 progress, Int32 retries)
   at Xabe.FFmpeg.Downloader.OfficialFFmpegDownloader.GetLatestVersion(String path, IProgress`1 progress, Int32 retries)
   at Xabe.FFmpeg.Downloader.FFmpegDownloader.GetLatestVersion(FFmpegVersion version, String path, IProgress`1 progress)
   at Xabe.FFmpeg.Downloader.FFmpegDownloader.GetLatestVersion(FFmpegVersion version, IProgress`1 progress)
theolivenbaum commented 2 years ago

@tomaszzmuda seems like the issue is really with the extra __MACOSX folder that is being included by mistake on the zip file by the ffbinaries project. Probably best to filter it out when extracting the zip file, instead of the approach taken by the PR from @alizamani84.

alizamani84 commented 2 years ago

@theolivenbaum We also got this issue in linux. It could be good to exclude the unnecessary paths/files, but this approach does not solve similar issues in the future if they release a new zip file with another directory structure (by mistake). If it happens again, then you need to take care of every single case and exclude directories/files. Anyway, both of these approaches (mine and yours) are just workarounds and I believe it makes more sense to embed the binary of specific version in our application and simply just not use the downloader in production as long as the downloader grabs the latest version. I don't know if it's possible, but it would be nice if the downloader has an option to specify the version that should be downloaded.

theolivenbaum commented 2 years ago

Totally agreed. @tomaszzmuda maybe could just release the binaries to NuGet? It should all be under the max package size. Happy to help if needed!

andrewdbond commented 1 year ago

An application is in production with FFmpegDownloader.GetLatestVersion, is it possible that the FFmpeg receive a breaking update which breaks something with the main Xabe.FFmpeg package?

The "Full" and "Shared" versions use downloads including https://xabe.net/ffmpeg/versions/ffmpeg-latest-win64-shared.zip which is from 2020.

The "Official" version it downloads uses https://ffbinaries.com/api/v1/version/latest which references version 4.4.1, which was released in 2021. https://ffmpeg.org/releases/

(Tested 2023-01-06)

tomaszzmuda commented 1 year ago

There is no good and reliable source of all FFmpeg builds. The best option is to provide it by yourself with all flags you need. Downloader is helpful on start but I discourage of using it in advanced and released projects.