Edit local media file metadata information - c#

I managed to download audio file from a remote source, and I want to change it's metadata, like Author, Title, Album.
I save it locally so it's easily accessible and editable, but I can't find anything to edit it's metadata.
I've tried:
Android.Media.MediaMetadataEditor but the error is pretty straightforward:
This class is obsoleted in this android platform
I'm using latest SDK (28) and API, for android Pie. And it is also stated on android developer documentation
This class was deprecated in API level 21.
Use MediaMetadata instead together with MediaSession.
I really searched for some example, and I didn't found anything useful, most of cases are with playlist.
I don't get how MediaSession can replace in any manner the MediaMetadataEditor, since MediaSession
Allows interaction with media controllers, volume keys, media buttons, and transport controls.
A MediaSession should be created when an app wants to publish media playback information or handle media keys
Instead MediaMetadata seems what I need because
Contains metadata about an item, such as the title, artist, etc.
And its Builder class is promising.
I'm sure that just reading that pages I should be able to understand how to do it, but after hours of trying, it seems I'm not experienced enough to learn from that documentation.
Is there an example to understand it?
Thanks

I found a solution outside android Library.
taglib-sharp seems working on android project, and it can be installed via nuget package, the name is TagLibSharp
Really easy to use:
TagLib.File my_file = TagLib.File.Create(path_to_my_file);
string[] performers = new string[1]{"My Performer"}
my_file.Tag.Title = "The real title";
my_file.Tag.Performers = performers;
my_file.Save();
Easy.

Related

How to get android's internal memory root in Unity?

I have seen many similar questions, seems like a lot of people trying to figure it out, I couldn't find any answer that would help me. I am making a simple app for Android using Unity.
I want to have a folder in android internal storage root, on my pc it looks like: huaweiP30\internal storage\videos\
I don't need to write anything to that folder, I want my app to list all the mp4 videos from that folder and be able to play them using unity video player, I want the user to be able to easily add more videos to it by just dropping them into that folder. I tested it on windows and the app is completed working as expected, all I need to do now is to give it the correct path to the internal storage.
Alternatively I could have the app list all .mp4 files on the whole storage if that's easier to do.
I I tried all the answers that I was able to find online, some of which worked for other people. Nothing has worked for me so far.
used this for testing on windows and works exactly how I want it. I just don't know what should I replace the path with to make it read from internal storage\videos\
string videosPath = "C:\Users\Admin\Downloads\";
string [] filePaths = Directory.GetFiles(videosPath,"*.mp4");
Please help me either solve it or find an alternative resolution, I appreciate any help.
Thanks in advance.
This was easier than I thought! I was researching for so long and already going crazy when all I had to do is - in my phone settings I went to permissions, memory and allowed my app to access the memory.
Then it's as simple as
string path = Application.persistentDataPath.Substring(0, Application.persistentDataPath.IndexOf("Android", StringComparison.Ordinal));
videosPath = path +"/videos/";
to get the path. without the last bit I was able to read every single video on my internal storage when I added
SearchOption.AllDirectories
here is how to make your app ask for permissions so you don't have to manually allow it.
https://docs.unity3d.com/Manual/android-RequestingPermissions.html
The sample code is about microphone but all you need to do is just change it to ExternalStorageRead/Write, don't worry about 'External', it works for internal memory too.

uwp app AdvancedQuerySyntax for video file types

in my uwp app I am getting video files from KnownFolder.VideoLibrary and I am using QueryOptions to get them, so taking advantage of that I am trying to use AdvancedQuerySyntax so that I only get video files, but I am actually getting subtitle files like srt as well. what am I doing wrong here? is the AQS syntax I wrote wrong? I think subs files are also considered as video files according to this syntax, is there a way I can narrow it down to getting only video files excluding subtitle files? or can I get a link to docs where I can know what is the list of extension types, this syntax actually will return? So I can manage it accordingly?
CODE
videoFileOptions = new QueryOptions()
{
IndexerOption = IndexerOption.OnlyUseIndexerAndOptimizeForIndexedProperties//check sort order later
};
string videoFilter = "System.Kind:=System.Kind#Video";
videoFileOptions.ApplicationSearchFilter += videoFilter;
videoFileOptions.SetPropertyPrefetch(PropertyPrefetchOptions.VideoProperties, RequiredVideoProperties);
videoFileOptions.SetThumbnailPrefetch(ThumbnailMode.VideosView, thumbnailRequestedSize, ThumbnailOptions.UseCurrentScale);
This is the line where I am providing the filter.
string videoFilter = "System.Kind:=System.Kind#Video";
Short answer: .srt and other subtitle files are classified as video files since any app supporting playback might want access to srt files.
You can add an application search filter ext:<>.srt to remove srt files from your results.
Long Answer: The inevitable question is why not have another type for Kind:Subtitles or something? Why include them for with Kind:Video?
Well there is another pressure that goes on the Kind mappings beyond just "does this extension make sense as a video"? It all comes back to the SD card access on Windows Phone.
See for Windows 8 an modern app accessing the SD card had to declare a file launch experience for any file type they wanted to see on the SD card. For example that meant that a video app would need a file launch experience for mp4, avi, ect. However, on Windows Phone this wouldn't work because there was no way for an app to override the default system app for mp4 or avi (there is another story here for another day). So we needed another way to give apps access to mp4 files on the SD card.
The solution was that since the UI already said "Grant this app access to Videos and your SD card" then any app with both the video library capability and SD card access should have access to all files of Kind.Video on your SD card. Thus Kind.Video not only meant "Video files" but also "Files a video app would want access to".
With this slightly changed definition, it meant that any files the built in video player needed were suddenly included in the Kinds.Video mapping. Which is where .srt files come from in the mapping.
And as one of the people responsible for making the kind mapping decisions, I'd like to take this opportunity to apologize my mess and promise I'm not nearly as brain dead as you'd think looking at this design. Probably

How to use Google Play Leaderboards in Xamarin / Monogame

Ok this is a simple question, but the Xamarin forums are pretty much useless...
I am trying to implement Leaderboards in my game that is built in MonoGame. Unfortunately, I can't seem to find the GameHelper class and I cannot extend BaseGameActivity as described in Google's how-to, even though I have the google play services component installed (19.0.1)
The only other alternative is using the GoogleApiClient, which I tried:
public IGoogleApiClient apiClient;
GoogleApiClientBuilder builder = new GoogleApiClientBuilder(this);
builder.AddApi(GamesClass.Api)
.AddApi(PlusClass.Api)
.AddScope(GamesClass.ScopeGames)
.AddScope(PlusClass.ScopePlusLogin);
apiClient = builder.Build();
But whenever I make a call to apiClient.Connect(), I get the following error:
E/GooglePlayServicesUtil( 7989): The Google Play services resources were not found.
Check your project configuration to ensure that the resources are included.
I have cleaned and rebuilt, removed the component and added the references manually, changed the location of the project to the root of the drive, all to no avail. I'm out of ideas. Anyone have leaderboards running in MonoGame?
I recently wrote a MonoGame project for Android, which includes Leaderboard support. You can find the full source here, but I would recommend looking at Activity1.cs in particular. It is where I do most of the Google Play work.
You can also take a look at GameOver.cs to see an instance of the leaderboard getting a score submitted to it.
That error message may not be the cause of your problem. I lifted the code and resources from BaseGame Utils and integrated it with my own project. I always get that message, and the game works perfectly.
I suggest you look carefully for any subsequent errors.

DirectShow.Net no combination of filters but fine in GSpot

I'm trying to use the DirectShot.Net wrapper from "http://directshownet.sourceforge.net/" to extract frames from a number of video files.
Whenever I run the DxScan sample app. I get a "No combination of intermediate filters could be found to make the connection." This happens for WMV files, MP4 files, AVI files. Any media I point at the sample app.
If I open any of the videos using the GSpot codec tool and ask it to render the graph, it does so without problem. So the machine is definitely capable of playing the content.
I'm on Win 7 64 bit. The same error is thrown targeting x64, x86 or Auto. Including running Visual Studio as an Administrator.
I've modified the sample code to try and find the correct pin containing the video media type as suggested by Romain R below.
I'm using:
IEnumPins epins;
capFilter.EnumPins(out epins);
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
IEnumMediaTypes mtypes;
pins[0].EnumMediaTypes(out mtypes);
AMMediaType[] types = new AMMediaType[1];
while(mtypes.Next(1, types, new IntPtr()) == 0){
var majorType = types[0].majorType;
if (majorType == MediaType.Video)
{
//This is never reached
}
}
}
For MP4 files, it's never hitting the commented line above. However for WMV files, the demo will now run correctly.
Presumably, this is because it isn't finding an appropriate MP4 file filter. Which is obscure as the content will play fine in windows media player.
Is this a likely cause?
DxScan sample is building a filter graph in an unreliable way, in particular is makes an assumption that the first pin it grabs from the source filter supplied for a media file is a video pin. It is not always the case. A better graph building approach should be working out fine. You might want to step through to find out at what line you have an error. Most likely, it is going to be connection of Sample Grabber Filter input pin.
UPD. Note that it might so happen that original filter has no input pins, it requires additional filters in between, so called parser/demultiplexer filters which convert streams into video frames and audio samples. DirectShow API offers Render* methods to assist in graph building in terms of suggesting required links of this chain and direct connection DxScan is doing might or might not work out.
That is, DxScan might be not the best sample to start from, MSDN samples/reference for native API are perhaps better for taking off the ground with DirectShow.
Your playground and primary research and API exploration tool should be GraphEdit from Windows SDK (GraphStudio, or GraphStudioNext as alternate improved options), not a DirectShow.NET wrapper library sample.
Which is obscure as the content will play fine in windows media player.
WMP does not use DirectShow for playback.

Getting duration of audio file C#

I'm trying to get the duration for an audio file in c#.
I got the following code to work on my local machine but when I deploy it to a windows server 2008 box it always returns a duration of 0 for .avi and .wav files.
WindowsMediaPlayerClass wmp = new WindowsMediaPlayerClass();
IWMPMedia mediaInfo = wmp.newMedia(filePath);
return mediaInfo.durationString
I have windows media player 11 installed on the server.
Any help would be most appreciated
I don't have experience with "WindowsMediaPlayerClass", but I have used TagLibSharp extensively, which is what I try to use for such things - it supports a pretty broad set of formats and that makes it's API much more usable that the built-in support in .NET
http://developer.novell.com/wiki/index.php/TagLib_Sharp
Quite possibly simply using TagLibSharp will solve your problems.
(Note that taglibsharp is maintained by the banshee project, but is hosted # novell for apparently historical reasons. I don't know about the details, but that can make contacting the devs a little confusing)
To retrieve duration info, media file must be opened first.
http://msdn.microsoft.com/en-us/library/windows/desktop/dd564790(v=vs.85).aspx#Y656
To retrieve the duration for files that are not in the user's library, you must wait for Windows Media Player to open the file; that is, the current OpenState must equal MediaOpen. You can verify this by handling the AxWindowsMediaPlayer._WMPOCXEvents_OpenStateChange event or by periodically checking the value of AxWindowsMediaPlayer.openState.
The link also has sample codes for C#.
If you don't like to play the video, you may use the IWMPMedia class:
http://johndyer.name/post/Retreiving-the-duration-of-a-WMV-in-C.aspx
My guess is that the media player isn't installed (it's not by default on server SKUs).
Did you try installing the desktop experience package?

Categories

Resources