Video Player in Android and Intent filter

619 views
Skip to first unread message

Degenerate Tech

unread,
Mar 21, 2021, 4:22:55 PM3/21/21
to Kivy users support
In Android file manager when I click on video file an popup is open and show all video player options so I can choose video player to play video file ...This is due to
 Intent filter in AndroidManifest.xml
But problem is how to pass video file path in my Kivy video player widget ..? I was reading intent will help to pass data from one activity to another activity in same or two different apps ..But I don't know how to do that ?via pyjnius 
Robert Flatt please help me ..

Robert

unread,
Mar 21, 2021, 7:04:27 PM3/21/21
to Kivy users support
If I correctly understand the question, look at this example, it receives a video share and plays it:

The intent filter is an xml file that is added to the Manifest with a Buildozer option.

Basically just set up a listener, this listens for the share, and when a share arrives it passes the contents to the rest of the app via a callback.
It is important the capabilities in the listener match those advertised to the OS in the intent filter.

The example copies the shared file using a method from SharedStorage. The copy is fast, but takes storage space.
If that is an issue in your app, presumably one might be able to redirect the shared stream but I have not tried that.
It is possible redirecting might take some trickery (or not?), but I really don't know (so don't ask).

Degenerate Tech

unread,
Mar 22, 2021, 7:27:12 AM3/22/21
to Kivy users support

Degenerate Tech

unread,
Mar 24, 2021, 2:37:44 PM3/24/21
to Kivy users support
HI @Robert Flatt  see once this intent filter ..using this when i am touching video file in file manager my kivy app showing .but i have to get path of video file 
please see this ..


<intent-filter>
   <action android:name="android.intent.action.VIEW" />
   <category android:name="android.intent.category.DEFAULT" />
   <category android:name="android.intent.category.BROWSABLE" />
   <category android:name="android.intent.category.OPENABLE" />

   <category android:name="android.intent.category.DEFAULT" />
   
   <data android:mimeType="video/mp4" />
   <data android:pathPattern=".*\\.mp4" />
   <data android:pathPattern=".*\\..*\\.mp4" />
   <data android:pathPattern=".*\\..*\\..*\\.mp4" />
   <data android:pathPattern=".*\\..*\\..*\\..*\\.mp4" />
</intent-filter>

Degenerate Tech

unread,
Mar 24, 2021, 2:38:04 PM3/24/21
to Kivy users support

Robert

unread,
Mar 24, 2021, 3:18:13 PM3/24/21
to Kivy users support
The intent filter tells Android what types of file your app can use.
The actual file (to which you want the path) is specified by the other app, and passed as a uri to your app.
You can get the path from the uri.

Of course you don't want the path, because your app don't have permission to read the file specified by the path.
You want to open a stream with the uri, and do something with that.

All this is coded in the example I referenced.

Degenerate Tech

unread,
Mar 24, 2021, 3:25:59 PM3/24/21
to Kivy users support
 why uri showing is none ?

    def to_file(self,uri,MIME_type):
        
        try:
            file_path = SharedStorage().retrieveUri(uri)
            self.video_callback(file_path,MIME_type)
        except Exception as e:
            print('ShareRcv.to_file() ' + str(e))

    def intent_handler(self,intent):
        print(intent.getAction())
        MIME_type = intent.getType()
        uri = intent.getParcelableExtra(Intent.EXTRA_STREAM)
        print(uri)
        if uri and self.video_callback:
            Thread(target=self.to_file, args=[uri,MIME_type],daemon=True).start()

       
        #if Intent.ACTION_VIEW == intent.getAction():
        print('!!!!!!!!!!!!!!!')
        MIME_type = intent.getType()
        if MIME_type == "text/plain":
            text = intent.getStringExtra(Intent.EXTRA_TEXT)
            if text and self.text_callback:
                self.text_callback(text,MIME_type)
        elif MIME_type == "video/mp4":
            print('!!!!!!!!!!!!!!!')
            uri = intent.getParcelableExtra(Intent.EXTRA_STREAM)
            if uri and se

Robert

unread,
Mar 24, 2021, 3:37:30 PM3/24/21
to Kivy users support
here?
uri = intent.getParcelableExtra(Intent.EXTRA_STREAM)
        print(uri)

No way for me to know.  Things you might look at....
The code does not filter the action type, that might be it?
Maybe it is something about the way the sender sent the attachment?
I can't debug your code for you.

Degenerate Tech

unread,
Mar 24, 2021, 4:27:48 PM3/24/21
to Kivy users support
Robert Flatt 
i  am using intent.getData() now see this error 
(i am testing share_rcv example )
 def intent_handler(self,intent):
        uri = intent.getData()
        #intent.getParcelableExtra(Intent.EXTRA_STREAM)
        MIME_type = intent.getType()
        Thread(target=self.to_file, args=[uri,MIME_type],
                           daemon=True).start()
        print(uri)
        if Intent.ACTION_VIEW ==

03-25 01:54:40.097 20767 20786 I python  : [INFO   ] [Base        ] Start application main loop
03-25 01:54:40.135 20767 20786 I python  : [INFO   ] [GL          ] NPOT texture support is available
03-25 01:54:40.481 20767 20819 I python  : ERROR SharedStorage.retrieveUri():
03-25 01:54:40.481 20767 20819 I python  : type object 'android.os.FileUtils' has no attribute 'copy'
03-25 01:54:40.515 20767 20819 I python  :
/storage/emulated/0/Android/data/org.test.receive/cache/FromSharedStorage/520ad0643d694cebbd68675ade898942.mp4
03-25 01:54:40.528 20767 20786 I python  : [ERROR  ] [Image       ] Error loading </storage/emulated/0/Android/data/org.test.receive/cache/FromSharedStorage/520ad0643d6
94cebbd68675ade898942.mp4>
03-25 01:54:40.566 20767 20844 I python  : [WARNING] [ffpyplayer  ] [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7d9658e000] Format mov,mp4,m4a,3gp,3g2,mj2 detected only with low score
of 1, misdetection possible!
03-25 01:54:40.567 20767 20844 I python  : [ERROR  ] [ffpyplayer  ] [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7d9658e000] moov atom not found
03-25 01:54:40.577 20767 20844 I python  : [ERROR  ] [ffpyplayer  ] /storage/emulated/0/Android/data/org.test.receive/cache/FromSharedStorage/520ad0643d694cebbd68675ade
898942.mp4: Invalid data found when processing input

Robert

unread,
Mar 24, 2021, 6:27:52 PM3/24/21
to Kivy users support
03-25 01:54:40.481 20767 20819 I python  : type object 'android.os.FileUtils' has no attribute 'copy'
This is the same as we discussed on Github

Degenerate Tech

unread,
Mar 25, 2021, 1:40:16 AM3/25/21
to Kivy users support
i was trying but  
844): ERROR SharedStorage.retrieveUri():
I/python  (22844): value too large to convert to unsigned char
I/python  (22844): /storage/emulated/0/Android/data/org.test.receive/cache/FromSharedStorage/a.mp4

new_file_loc = self._save_to()
                new_file_path= join(new_file_loc, file_name)
                # Copy
                rs = mActivity.getContentResolver().openInputStream(someUri)
                ws = FileOutputStream(new_file_path)
                if api_version>=29:
                    FileUtils.copy(rs,ws)
                else:
                    initialstream=rs
                    buffer=[initialstream.available()]
                    initialstream.read(buffer)
                    ws.write(buffer)
                    
                ws.flush()
                ws.close()
                rs.close()

Degenerate Tech

unread,
Mar 25, 2021, 2:31:58 AM3/25/21
to Kivy users support
DONE Hurrah yes 
 Robert Flatt 

  # for other uris retun the uri as a string
    def retrieveUri(self, someUri):  
        new_file_path = ''
        try:
            if someUri:
                someUri = cast('android.net.Uri',someUri)
                scheme = someUri.getScheme().lower()
                if scheme == 'content':
                    context = mActivity.getApplicationContext()
                    cursor = context.getContentResolver().query(someUri, None,
                                                                None, None,
                                                                None)
                    dn = MediaStoreMediaColumns.DISPLAY_NAME
                    nameIndex = cursor.getColumnIndex(dn)
                    cursor.moveToFirst()
                    file_name = cursor.getString(nameIndex)
                    cursor.close()
                elif scheme == 'file':
                    file_name = basename(someUri.getPath())
                else:
                    return someUri.toString()
                new_file_loc = self._save_to()
                new_file_path= join(new_file_loc, file_name)
                # Copy
                rs = mActivity.getContentResolver().openInputStream(someUri)
                ws = FileOutputStream(new_file_path)
                if api_version>=29:
                    FileUtils.copy(rs,ws)
                else:
                    initialstream=rs
                    buffer=[1024]
                    while((initialstream.read(buffer))>0):
                        x=initialstream.read(buffer)
                        ws.write(buffer,0,x)
                ws.flush()
                ws.close()
                rs.close()
        except Exception as e:
            print('ERROR SharedStorage.retrieveUri():\n' + str(e))
            return  someUri.getPath()
        return new_file_path

Degenerate Tech

unread,
Mar 25, 2021, 2:33:52 AM3/25/21
to Kivy users support
Now my video player can play from gallery  ....
I/python  (30940): [INFO   ] [GL          ] Texture max units <8>
I/python  (30940): [INFO   ] [Window      ] auto add sdl2 input provider
I/python  (30940): [INFO   ] [Window      ] virtual keyboard not allowed, single mode, not docked
I/python  (30940): <android.net.Uri at 0xa02c6910 jclass=android/net/Uri jself=<LocalRef obj=0x10b2 at 0xa02c10f0>>
I/python  (30940): ERROR SharedStorage.retrieveUri():
I/python  (30940): value too large to convert to unsigned char
I/python  (30940): /storage/emulated/0/a.mp4
I/python  (30940): [WARNING] [Base        ] Unknown <android> provider
I/python  (30940): [INFO   ] [Base        ] Start application main loop
I/python  (30940): [INFO   ] [GL          ] NPOT texture support is available
I/python  (30940): [ERROR  ] [Image       ] Error loading </storage/emulated/0/a.mp4>
I/python  (30940): [WARNING] [ffpyplayer  ] [swscaler @ 0xa0630000] No accelerated colorspace conversion found from yuv420p to rgba.

Robert

unread,
Mar 25, 2021, 3:05:19 AM3/25/21
to Kivy users support
Congratulations.

Looks like you have a one (maybe two) things to look at. But you'll get there.

Degenerate Tech

unread,
Mar 25, 2021, 4:47:09 AM3/25/21
to Kivy users support
This is working file in android 8

 # for other uris retun the uri as a string
    def retrieveUri(self, someUri):  
        new_file_path = ''
        try:
            if someUri:
                someUri = cast('android.net.Uri',someUri)
                scheme = someUri.getScheme()
                print(f'hello=================={scheme}')
                if str(scheme) == "content":
                    print('###########################################')
                    context = mActivity.getApplicationContext()
                    cursor = context.getContentResolver().query(someUri, None,
                                                                None, None,
                                                                None)
                    if cursor==None:
                        return someUri.getPath()
                    else:
                        cursor.moveToFirst()
                        idx = cursor.getColumnIndex(MediaStoreMediaColumns.DATA)
                        return cursor.getString(idx);
                    
                # rs.close()
        except Exception as e:
            print('ERROR SharedStorage.retrieveUri():\n' + str(e))
            return No

Robert

unread,
Mar 25, 2021, 12:55:36 PM3/25/21
to Kivy users support
That is clever.

Clearly it wont work on 29+, but that is OK because we have the other method in that case.

It would be good to test on 28.

Degenerate Tech

unread,
Mar 26, 2021, 6:26:47 AM3/26/21
to Kivy users support
For 29+ api you are coping that file .. think if the video is very large in size !!
So this is not good solution..are you sure above code will not work on 29+ api ?
I don't have Android 10 physical Phone ..so I can't test .

Robert

unread,
Mar 26, 2021, 12:27:50 PM3/26/21
to Kivy users support
yes

Degenerate Tech

unread,
Mar 26, 2021, 2:45:53 PM3/26/21
to Kivy users support
Okk..tell me one separate thing now How to give write Settings permission in new er version of Android. Only writting in permission in buildozer not enough I think ..I am using plyer brightNess  and I have written Writtesetting permission in buildozer .. bright Ness controll working on Android 5 but in android 8 I have to give permission manually by opening android settings..then I can change brightness in android 8

--
You received this message because you are subscribed to a topic in the Google Groups "Kivy users support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/kivy-users/YLoeAMHYlgY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to kivy-users+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/kivy-users/e1a81ccf-4485-43c1-88d2-1479c770b1bcn%40googlegroups.com.

Robert

unread,
Mar 26, 2021, 4:54:47 PM3/26/21
to Kivy users support

Degenerate Tech

unread,
Mar 27, 2021, 2:48:27 AM3/27/21
to Kivy users support
for android 5 it is well but for android 8 it is working after giving permission manually(via android settings ) 

Degenerate Tech

unread,
Mar 27, 2021, 11:26:55 AM3/27/21
to Kivy users support
@Robert Flatt 
One problem in sharercv example 
when i open a file from file manager kivy app showing that file  properly .but when i pause kivy app and open a different file from file manager kivy app opening previous file .. when i close kivy app and then i can open different file from file manager .

Robert

unread,
Mar 27, 2021, 4:02:21 PM3/27/21
to Kivy users support
Good test. Can you figure out how to add the functionality?

Degenerate Tech

unread,
Mar 27, 2021, 4:20:46 PM3/27/21
to Kivy users support

I think ..When we opening file from file manager I have to stop python Kivy activity first then start again ..

Robert

unread,
Mar 27, 2021, 7:19:12 PM3/27/21
to Kivy users support
Android only has one UI activity active at a time (except split screen) , the others are all paused.
When the file manager is active, Kivy app is paused (does not do anything, including listen for new intents)
So on_resume .....

Degenerate Tech

unread,
Mar 30, 2021, 4:56:23 AM3/30/21
to Kivy users support

so how to solve this problem ?

Robert

unread,
Mar 30, 2021, 1:08:54 PM3/30/21
to Kivy users support
Look at how the listener works when the app is first built and when the app is not paused (they are different cases, you found another case).

Robert

unread,
Mar 30, 2021, 9:20:07 PM3/30/21
to Kivy users support
I now think I didn't understand the issue explanation.
Please explain again as clearly as possible what you see.
Thanks

Degenerate Tech

unread,
Mar 31, 2021, 5:12:48 AM3/31/21
to Kivy users support
watch video

sharercv.py
2021-03-31-14-29-11_xHDqWVPB.mp4
storage.py

Robert

unread,
Mar 31, 2021, 1:16:09 PM3/31/21
to Kivy users support
I don't see that here (on A11) a new share replaces the currently playing share.

I'll let you know if I discover what is different.


On Tuesday, March 30, 2021 at 11:12:48 PM UTC-10 sksah...@gmail.com wrote:
watch video

Degenerate Tech

unread,
Mar 31, 2021, 1:30:46 PM3/31/21
to Kivy users support
see python scripts I did some modifications.

--
You received this message because you are subscribed to a topic in the Google Groups "Kivy users support" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/kivy-users/YLoeAMHYlgY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to kivy-users+...@googlegroups.com.

Robert

unread,
Mar 31, 2021, 4:21:38 PM3/31/21
to Kivy users support
Perhaps the previous stream was not closed?

Degenerate Tech

unread,
Mar 31, 2021, 4:29:23 PM3/31/21
to Kivy users support
When I am pausing Kivy app and open different file Kivy app loading previous file as to see just use print() file name in storage.py and share.py scripts

Robert

unread,
Mar 31, 2021, 11:11:40 PM3/31/21
to Kivy users support
I don't see this (A6), I see other issues which I am not clear about. But not this one.

Robert

unread,
Apr 1, 2021, 8:28:02 PM4/1/21
to Kivy users support
I updated storage.py , now works on Android 6.
Note there is now an additional directory storage_src and this is specified in .spec

FYI if you are testing, Uri structure can vary according to its source, for example Android Files creates different uris to a third party file manager.

Degenerate Tech

unread,
Apr 2, 2021, 1:52:11 AM4/2/21
to Kivy users support
what about this problem in video?

Robert

unread,
Apr 2, 2021, 1:05:48 PM4/2/21
to Kivy users support
What problem?

Degenerate Tech

unread,
Apr 2, 2021, 2:29:20 PM4/2/21
to Kivy users support
I have uploaded a video .. watch it

Robert

unread,
Apr 2, 2021, 4:01:29 PM4/2/21
to Kivy users support
Yes I saw that, I have been unable to replicate.
I assumed it was an artifact of the changes there, or the file manager used there.
Which is why I started testing with more than one file manager.
But I still could not replicate what is demonstrated in the video.

Can you demonstrate with the current code on GitHub?
Does it make a difference which file manager is used?

Degenerate Tech

unread,
Apr 13, 2021, 5:32:05 PM4/13/21
to Kivy users support
I have tested in different file managers but this problem exists..it can get right file name  for first opening Kivy app ..but when Kivy app paused and I choose different file from file manager it opens previous file ..I have seen same file name is showing in storage.py (print () I used )..
Okk I will upload in GitHub for better understanding.

Degenerate Tech

unread,
Apr 14, 2021, 1:40:41 AM4/14/21
to Kivy users support
i think some problem is here  because it is showing previous file 
# for other uris retun the uri as a string
    def retrieveUri(self, someUri):  
        new_file_path = ''
        try:
            if someUri:
                sUri = cast('android.net.Uri',someUri)
                scheme = sUri.getScheme()
                print(f'hello=================={scheme}')
                if str(scheme) == "content":
                    print('###########################################')
                    context = mActivity.getApplicationContext()
                    cursor = context.getContentResolver().query(sUri, None,
                                                                None, None,
                                                                None)
                    if cursor==None:
                        return sUri.getPath()
                    else:
                        cursor.moveToFirst()
                        idx = cursor.getColumnIndex(MediaStoreMediaColumns.DATA)
                        return cursor.getString(idx);
                    
                # rs.close()
        except Exception as e:
            print('ERROR SharedStorage.retrieveUri():\n' + str(e))
            return None

Degenerate Tech

unread,
Apr 14, 2021, 1:41:27 AM4/14/21
to Kivy users support
       return sUri.getPath()
                    else:
                        cursor.moveToFirst()
                        idx = cursor.getColumnIndex(MediaStoreMediaColumns.DATA)
                        print('$$$$$$$$$$')
                        print(cursor.getString(idx))
                        print('$$$$$$$$$$$')

Degenerate Tech

unread,
Apr 14, 2021, 3:56:04 AM4/14/21
to Kivy users support
@Robert Flatt i have observed one thing please see once 
 see def __ init__() when kivy app start first time it is calling self.intent_handler(self.intent) so video file getting uri  but after pause kivy app 
when i have commented  line  no 10 it is detected .

activity.bind(on_new_intent=self.intent_handler)  this is not calling self.intent_handler ,when i choose another file from file manager  i am 100% sure some problem is here  

class ShareRcv():
    # Must be instantiated in App.build() 

    def __init__(self,text_callback=None,video_callback=None):              
        self.text_callback=text_callback
        self.video_callback=video_callback
        self.intent = mActivity.getIntent()
  10     #self.intent_handler(self.intent)
        activity.bind(on_new_intent=self.intent_handler)
    
    def to_file(self,uri,MIME_type):
        try:
            file_path = SharedStorage().retrieveUri(uri)
            self.video_callback(file_path,MIME_type)
        except Exception as e:
            print('ShareRcv.to_file() ' + str(e))

    def intent_handler(self,intentx):
        uri=None
        intent= mActivity.getIntent()
        uri = intent.getData()
        print('======================%',uri)
        #intent.getParcelableExtra(Intent.EXTRA_STREAM)
        MIME_type = intent.getType()
        self.to_file(uri, MIME_type)
        #Thread(target=self.to_file, args=[uri,MIME_type],daemon=True).start()
        print(uri)
        # if Intent.ACTION_VIEW == intent.getAction():
        #     MIME_type = intent.getType()
        #     if MIME_type == "text/plain":
        #         text = intent.getStringExtra(Intent.EXTRA_TEXT)
        #         if text and self.text_callback:
        #             self.text_callback(text,MIME_type)
        #     elif MIME_type == "video/mp4":
        #         uri = Intent.getParcelableExtra(Intent.EXTRA_STREAM)
        #         if uri and self.video_callback:
        #             Thread(target=self.to_file, args=[uri,MIME_type],
        #                    daemon=True).start()

Degenerate Tech

unread,
Apr 14, 2021, 4:59:20 AM4/14/21
to Kivy users support

Robert

unread,
Apr 14, 2021, 12:57:15 PM4/14/21
to Kivy users support
As I have said before, I cannot replicate what you see.

And yes I previously suggested adding a call to the intent_handler (like line 40) on_resume.

Degenerate Tech

unread,
Apr 14, 2021, 2:22:54 PM4/14/21
to Kivy users support
activity.bind(on_new_intent=self.intent_handler) 
tell me on_new_intent calling self.intent_handler  in your code?  

Robert

unread,
Apr 14, 2021, 8:12:39 PM4/14/21
to Kivy users support
I don't understand the question.

Degenerate Tech

unread,
Apr 25, 2021, 1:44:36 PM4/25/21
to Kivy users support

def __init__(self,text_callback=None,video_callback=None):

self.text_callback=text_callback

self.video_callback=video_callback

self.intent = mActivity.getIntent()

self.intent_handler(self.intent)

activity.bind(on_new_intent=self.intent_handler)


 this line in  your code not calling self.intent_handler  method when new intent coming .

Degenerate Tech

unread,
Apr 25, 2021, 3:28:29 PM4/25/21
to Kivy users support
see these file once
main.py
intent_filter.xml
storage.py
sharercv.py
buildozer.spec

Robert

unread,
Apr 25, 2021, 3:48:21 PM4/25/21
to Kivy users support
Looking at your code (and maybe I missed something, because debugging other people's code is not something that interests me) the listener will not be active because the bind does not occur because the __init__() of the ShareRcv class is not called, because ShareRcv() is not instantiated. 

It looks like you have main.py from a different app. 😂

Degenerate Tech

unread,
May 27, 2021, 5:23:21 PM5/27/21
to Kivy users support
problem solved .. now my kivy video player app getting new intent from other file manager  .yes 
Thanks Robert ..i am learning from your pyjnius code .you are working great..
And I have  implemented  successfully Android's VideoView widget in kivy app. 

Degenerate Tech

unread,
May 27, 2021, 5:33:49 PM5/27/21
to Kivy users support
See Android VideoView .. 

 😀😀😀

Screenshot_20210528-030006.jpg

Robert

unread,
May 27, 2021, 7:56:21 PM5/27/21
to Kivy users support
That is great. Glad it all worked.
Reply all
Reply to author
Forward
0 new messages