Recherche avancée

Médias (91)

Autres articles (16)

  • Les tâches Cron régulières de la ferme

    1er décembre 2010, par

    La gestion de la ferme passe par l’exécution à intervalle régulier de plusieurs tâches répétitives dites Cron.
    Le super Cron (gestion_mutu_super_cron)
    Cette tâche, planifiée chaque minute, a pour simple effet d’appeler le Cron de l’ensemble des instances de la mutualisation régulièrement. Couplée avec un Cron système sur le site central de la mutualisation, cela permet de simplement générer des visites régulières sur les différents sites et éviter que les tâches des sites peu visités soient trop (...)

  • Configuration spécifique pour PHP5

    4 février 2011, par

    PHP5 est obligatoire, vous pouvez l’installer en suivant ce tutoriel spécifique.
    Il est recommandé dans un premier temps de désactiver le safe_mode, cependant, s’il est correctement configuré et que les binaires nécessaires sont accessibles, MediaSPIP devrait fonctionner correctement avec le safe_mode activé.
    Modules spécifiques
    Il est nécessaire d’installer certains modules PHP spécifiques, via le gestionnaire de paquet de votre distribution ou manuellement : php5-mysql pour la connectivité avec la (...)

  • Contribute to documentation

    13 avril 2011

    Documentation is vital to the development of improved technical capabilities.
    MediaSPIP welcomes documentation by users as well as developers - including : critique of existing features and functions articles contributed by developers, administrators, content producers and editors screenshots to illustrate the above translations of existing documentation into other languages
    To contribute, register to the project users’ mailing (...)

Sur d’autres sites (4309)

  • A Quick Start Guide to the Payment Services Directive (PSD2)

    22 novembre 2024, par Daniel Crough — Banking and Financial Services, Privacy

    In 2023, there were 266.2 billion real-time payments indicating that the demand for secure transactions has never been higher. As we move towards a more open banking system, there are a host of new payment solutions that offer convenience and efficiency, but they also present new risks.

    The Payment Services Directive 2 (PSD2) is one of many regulations established to address these concerns. PSD2 is a European Union (EU) business initiative to offer smooth payment experiences while helping customers feel safe from online threats. 

    In this post, learn what PSD2 includes, how it improves security for online payments, and how Matomo supports banks and financial institutions with PSD2 compliance.

    What is PSD2 ? 

    PSD2 is an EU directive that aims to improve the security of electronic payments across the EU. It enforces strong customer authentication and allows third-party access to consumer accounts with explicit consent. 

    Its main objectives are :

    • Strengthening security and data privacy measures around digital payments.
    • Encouraging innovation by allowing third-party providers access to banking data.
    • Improving transparency with clear communication regarding fees, terms and conditions associated with payment services.
    • Establishing a framework for sharing customer data securely through APIs for PSD2 open banking.

    Rationale behind PSD2 

    PSD2’s primary purpose is to engineer a more integrated and efficient European payment market without compromising the security of online transactions. 

    The original directive aimed to standardise payment services across EU member states, but as technology evolved, an updated version was needed.

    PSD2 is mandatory for various entities within the European Economic Area (EEA), like :

    • Banks and credit institutions
    • Electronic money institutions or digital banks like Revolut
    • Card issuing and acquiring institutions
    • Fintech companies
    • Multi-national organisations operating in the EU

    PSD2 implementation timeline

    With several important milestones, PSD2 has reshaped how payment services work in Europe. Here’s a closer look at the pivotal events that paved the way for its launch.

    • 2002 : The banking industry creates the European Payments Council (EC), which drives the Single Euro Payments Area (SEPA) initiative to include non-cash payment instruments across European regions. 
    • 2007 : PSD1 goes into effect.
    • 2013 : EC proposes PSD2 to include protocols for upcoming payment services.
    • 2015 : The Council of European Union passes PSD2 and gives member states two years to incorporate it.
    • 2018 : PSD2 goes into effect. 
    • 2019 : The final deadline for all companies within the EU to comply with PSD2’s regulations and rules for strong customer authentication. 

    PSD2 : Key components 

    PSD2 introduces several key components. Let’s take a look at each one.

    Strong Customer Authentication (SCA)

    The Regulatory Technical Standards (RTS) under PSD2 outline specific requirements for SCA. 

    SCA requires multi-factor authentication for online transactions. When customers make a payment online, they need to verify their identity using at least two of the three following elements :

    • Knowledge : Something they know (like a password, a code or a secret answer)
    • Possession : Something they have (like their phone or card)
    • Inherence : Something they are (like biometrics — fingerprints or facial features)
    Strong customer authentication three factors

    Before SCA, banks verified an individual’s identity only using a password. This dual verification allows only authorised users to complete transactions. SCA implementation reduces fraud and increases the security of electronic payments.

    SCA implementation varies for different payment methods. Debit and credit cards use the 3D Secure (3DS) protocol. E-wallets and other local payment measures often have their own SCA-compliant steps. 

    3DS is an extra step to authenticate a customer’s identity. Most European debit and credit card companies implement it. Also, in case of fraudulent chargebacks, the issuing bank becomes liable due to 3DS, not the business. 

    However, in SCA, certain transactions are exempt : 

    • Low-risk transactions : A transaction by an issuer or an acquirer whose fraud level is below a specific threshold. If the acquirer feels that a transaction is low risk, they can request to skip SCA. 
    • Low-value transactions : Transactions under €30.
    • Trusted beneficiaries : Trusted merchants customers choose to safelist.
    • Recurring payments : Recurring transactions for a fixed amount are exempt from SCA after the first transaction.

    Third-party payment service providers (TPPs) framework

    TPPs are entities authorised to access customer banking data and initiate payments. There are three types of TPPs :

    Account Information Service Providers (AISPs)

    AISPs are services that can view customers’ account details, but only with their permission. For example, a budgeting app might use AISP services to gather transaction data from a user’s bank account, helping them monitor expenses and oversee finances. 

    Payment Initiation Service Providers (PISPs)

    PISPs enable clients to initiate payments directly from their bank accounts, bypassing the need for conventional payment options such as debit or credit cards. After the customer makes a payment, PISPs immediately contact the merchant to ensure the user can access the online services or products they bought. 

    Card-Based Payment Instruments (CBPII)

    CBPIIs refer to services that issue payment cards linked to customer accounts. 

    Requirements for TPPs

    To operate effectively under PSD2, TPPs must meet several requirements :

    Consumer consent : Customers must explicitly authorise TPPs to retrieve their financial data. This way, users can control who can view their information and for what purpose.

    Security compliance : TPPs must follow SCA and secure communication guidelines to protect users from fraud and unauthorised access.

    API availability : Banks must make their Application Programming Interfaces (APIs) accessible and allow TPPs to connect securely with the bank’s systems. This availability helps in easy integration and lets TPPs access essential data. 

    Consumer protection methods

    PSD2 implements various consumer protection measures to increase trust and transparency between consumers and financial institutions. Here’s a closer look at some of these key methods :

    • Prohibition of unjustified fees : PSD2 requires banks to clearly communicate any additional charges or fees for international transfers or account maintenance. This ensures consumers are fully aware of the actual costs and charges.
    • Timely complaint resolution : PSD2 mandates that payment service providers (PSPs) have a straightforward complaint procedure. If a customer faces any problems, the provider must respond within 15 business days. This requirement encourages consumers to engage more confidently with financial services.
    • Refund in case of unauthorised payment : Customers are entitled to a full refund for payments made without their consent.
    • Surcharge ban : Additional charges on credit and debit card payments aren’t allowed. Businesses can’t impose extra fees on these payment methods, which increases customers’ purchasing power.

    Benefits of PSD2 

    Businesses — particularly those in banking, fintech, finserv, etc. — stand to benefit from PSD2 in several ways.

    Access to customer data

    With customer consent, banks can analyse spending patterns to develop tailored financial products that match customer needs, from personalised savings accounts to more relevant loan offerings.

    Innovation and cost benefits 

    PSD2 opened payment processing up to more market competition. New payment companies bring fresh approaches to banking services, making daily transactions more efficient while driving down processing fees across the sector.

    Also, banks now work alongside payment technology providers, combining their strengths to create better services. This collaboration brings faster payment options to businesses, helping them stay competitive while reducing operational costs.

    Improved customer trust and experience

    Due to PSD2 guidelines, modern systems handle transactions quickly without compromising the safety of payment data, creating a balanced approach to digital banking.

    PSD2 compliance benefits

    Banking customers now have more control over their financial information. Clear processes allow consumers to view and adjust their financial preferences as needed.

    Strong security standards form the foundation of these new payment systems. Payment provider platforms must adhere to strict regulations and implement additional protection measures.

    Challenges in PSD2 compliance 

    What challenges can banks and financial institutions face regarding PSD2 compliance ? Let’s examine them. 

    Resource requirements

    For many businesses, the new requirements come with a high price tag. PSD2 requires banks and fintechs to build and update their systems so that other providers can access customer data safely. For example, they must develop APIs to allow TPPs to acquire customer data. 

    Many banks still use older systems that can’t meet PSD2’s added requirements. In addition to the cost of upgrades, complying with PSD2 requires banks to devote resources to training staff and monitoring compliance.

    The significant costs required to update legacy systems and IT infrastructure while keeping services running remain challenging.

    Risks and penalties

    Organisations that fail to comply with PSD2 regulations can face significant penalties.

    Additionally, the overlapping requirements of PSD2 and other regulations, such as the General Data Protection Regulation (GDPR), can create confusion. 

    Banks need clear agreements with TPPs about who’s responsible when things go wrong. This includes handling data breaches, preventing data misuse and protecting customer information. 

    Increased competition 

    Introducing new players in the financial ecosystem, such as AISPs and PISPs, creates competition. Banks must adapt their services to stay competitive while managing compliance costs.

    PSD2 aims to protect customers but the stronger authentication requirements can make banking less convenient. Banks must balance security with user experience. Focused time, effort and continuous monitoring are needed for businesses to stay compliant and competitive.

    How Matomo can help 

    Matomo gives banks and financial institutions complete control over their data through privacy-focused web analytics, keeping collected information internal rather than being used for marketing or other purposes. 

    Its advanced security setup includes access controls, audit logs, SSL encryption, single sign-on and two-factor authentication. This creates a secure environment where sensitive data remains accessible only to authorised staff.

    While prioritizing privacy, Matomo provides tools to understand user flow and customer segments, such as session recordings, heatmaps and A/B testing.

    Financial institutions particularly benefit from several key features : 

    • Tools for obtaining explicit consent before processing personal data like this Do Not Track preference
    • Insights into how financial institutions integrate TPPs (including API usage, user engagement and potential authentication drop-off points)
    • Tracking of failed login attempts or unusual access patterns
    • IP anonymization to analyse traffic patterns and detect potential fraud
    Matomo's Do Not Track preference selection screen

    PSD3 : The next step 

    In recent years, we have seen the rise of innovative payment companies and increasingly clever fraud schemes. This has prompted regulators to propose updates to payment rules.

    PSD3’s scope is to adapt to the evolving digital transformation and to better handle these fraud risks. The proposed measures : 

    • Encourage PSPs to share fraud-related information.
    • Make customers aware of the different types of fraud.
    • Strengthen customer authentication standards.
    • Provide non-bank PSPs restricted access to EU payment systems. 
    • Enact payment rules in a directly applicable regulation and harmonise and enforce the directive.

    Web analytics that respect user privacy 

    Achieving compliance with PSD2 may be a long road for some businesses. With Matomo, organisations can enjoy peace of mind knowing their data practices align with legal requirements.

    Ready to stop worrying over compliance with regulations like PSD2 and take control of your data ? Start your 21-day free trial with Matomo.

  • Six Best Amplitude Alternatives

    10 décembre 2024, par Daniel Crough

    Product analytics is big business. Gone are the days when we could only guess what customers were doing with our products or services. Now, we can track, visualise, and analyse how they interact with them and, with that, constantly improve and optimise. 

    The problem is that many product analytics tools are expensive and complicated — especially for smaller businesses. They’re also packed with functionality more attuned to the needs of massive companies. 

    Amplitude is such a tool. It’s brilliant and it has all the bells and whistles that you’ll probably never need. Fortunately, there are alternatives. In this guide, we’ll explore the best of those alternatives and, along the way, provide the insight you’ll need to select the best analytics tool for your organisation. 

    Amplitude : a brief overview

    To set the stage, it makes sense to understand exactly what Amplitude offers. It’s a real-time data analytics tool for tracking user actions and gaining insight into engagement, retention, and revenue drivers. It helps you analyse that data and find answers to questions about what happened, why it happened, and what to do next.

    However, as good as Amplitude is, it has some significant disadvantages. While it does offer data export functionality, that seems deliberately restricted. It allows data exports for specific events, but it’s not possible to export complete data sets to manipulate or format in another tool. Even pulling it into a CSV file has a 10,000-row limit. There is an API, but not many third-party integration options.

    Getting data in can also be a problem. Amplitude requires manual tags on events that must be tracked for analysis, which can leave holes in the data if every possible subsequent action isn’t tagged. That’s a time-consuming exercise, and it’s made worse because those tags will have to be updated every time the website or app is updated. 

    As good as it is, it can also be overwhelming because it’s stacked with features that can create confusion for novice or inexperienced analysts. It’s also expensive. There is a freemium plan that limits functionality and events. Still, when an organisation wants to upgrade for additional functionality or to analyse more events, the step up to the paid plan is massive.

    Lastly, Amplitude has made some strides towards being a web analytics option, but it lacks some basic functionality that may frustrate people who are trying to see the full picture from web to app.

    Snapshot of Amplitude alternatives

    So, in place of Amplitude, what product analytics tools are available that won’t break the bank and still provide the functionality needed to improve your product ? The good news is that there are literally hundreds of alternatives, and we’ve picked out six of the best.

    1. Matomo – Best privacy-focused web and mobile analytics
    2. Mixpanel – Best for product analytics
    3. Google Analytics – Best free option
    4. Adobe Analytics – Best for predictive analytics
    5. Umami – Best lightweight tool for product analytics
    6. Heap – Best for automatic user data capture

    A more detailed analysis of the Amplitude alternatives

    Now, let’s dive deeper into each of the six Amplitude alternatives. We’ll cover standout features, integrations, pricing, use cases and community critiques. By the end, you’ll know which analytics tool can help optimise website and app performance to grow your business.

    1. Matomo – Best privacy-friendly web and app analytics

    Privacy is a big concern these days, especially for organisations with a presence in the European Union (EU). Unlike other analytics tools, Matomo ensures you comply with privacy laws and regulations, like the General Data Protection Regulation (GDPR) and California’s Consumer Privacy Act (CCPA).

    Matomo helps businesses get the insights they need without compromising user privacy. It’s also one of the few self-hosted tools, ensuring data never has to leave your site.

    Matomo is open-source, which is also rare in this class of tools. That means it’s available for anyone to adapt and customise as they wish. Everything you need to build custom APIs is there.

    Image showing the origin of website traffic.
    The Locations page in Matomo shows the countries, continents, regions, and cities where website traffic originates.

    Its most useful capabilities include visitor logs and session recordings to trace the entire customer journey, spot drop-off points, and fine-tune sales funnels. The platform also comes with heatmaps and A/B testing tools. Heatmaps provide a useful visual representation of your data, while A/B testing allows for more informed, data-driven decisions.

    Despite its range of features, many reviewers laud Matomo’s user interface for its simplicity and user-friendliness. 

    Why Matomo : Matomo is an excellent alternative because it fills in the gaps where Amplitude comes up short, like with cookieless tracking. Also, while Amplitude focuses mainly on behavioural analytics, Matomo offers both behavioural and traditional analytics, which allows more profound insight into your data. Furthermore, Matomo fully complies with the strictest privacy regulations worldwide, including GDPR, LGPD, and HIPAA.

    Standout features include multi-touch attribution, visits log, content engagement, ecommerce, customer segments, event tracking, goal tracking, custom dimensions, custom reports, automated email reports, tag manager, sessions recordings, roll-up reporting that can pull data from multiple websites or mobile apps, Google Analytics importer, Matomo tag manager, comprehensive visitor tracking, heatmaps, and more.

    Integrations with 100+ technologies, including Cloudflare, WordPress, Magento, Google Ads, Drupal, WooCommerce, Vue, SharePoint and Wix.

    Pricing is free for Matomo On-Premise and $23 per month for Matomo Cloud, which comes with a 21-day free trial (no credit card required).

    Strengths

    • Privacy focused
    • Cookieless consent banners
    • 100% accurate, unsampled data
    • Open-source code 
    • Complete data ownership (no sharing with third parties)
    • Self-hosting and cloud-based options
    • Built-in GDPR Manager
    • Custom alerts, white labelling, dashboards and reports

    Community critiques 

    • Premium features are expensive and proprietary
    • Learning curve for non-technical users

    2. Mixpanel – Best for product analytics

    Mixpanel is a dedicated product analytics tool. It tracks and analyses customer interactions with a product across different platforms and helps optimise digital products to improve the user experience. It works with real-time data and can provide answers from customer and revenue data in seconds.

    It also presents data visualisations to show how customers interact with products.

    Screenshot reflecting useful customer trends

    Mixpanel allows you to play around filters and views to reveal and chart some useful customer trends. (Image source)

    Why Mixpanel : One of the strengths of this platform is the ability to test hypotheses. Need to test an ambitious idea ? Mixpanel data can do it with real user analytics. That allows you to make data-driven decisions to find the best path forward.

    Standout features include automatic funnel segment analysis, behavioural segmentation, cohort segmentation, collaboration support, customisable dashboards, data pipelines, filtered data views, SQL queries, warehouse connectors and a wide range of pre-built integrations.

    Integrations available include Appcues, AppsFlyer, AWS, Databox, Figma, Google Cloud, Hotjar, HubSpot, Intercom, Integromat, MailChimp, Microsoft Azure, Segment, Slack, Statsig, VWO, Userpilot, WebEngage, Zapier, ZOH) and dozens of others.

    Pricing starts with a freemium plan valid for up to 20 million events per month. The growth plan is affordable at $25 per month and adds features like no-code data transformations and data pipeline add-ons. The enterprise version runs at a monthly cost of $833 and provides the full suite of features and services and premium support.

    There’s a caveat. Those prices only allow up to 1,000 Monthly Tracked Users (MTUs), calculated based on the number of visitors that perform a qualifying event each month. Beyond that, MTU plans start at $20,000 per year.

    Strengths

    • User behaviour and interaction tracking
    • Unlimited cohort segmentation capabilities
    • Drop-off analysis showing where users get stuck
    • A/B testing capabilities

    Community critiques 

    • Expensive enterprise features
    • Extensive setup and configuration requirements

    3. Google Analytics 4 – Best free web analytics tool

    The first thing to know about Google Analytics 4 is that it’s a web analytics tool. In other words, it tracks sessions, not user behaviours in app environments. It can provide details on how people found your website and how they go there, but it doesn’t offer much detail on how people use your product. 

    There is also an enterprise version, Google Analytics 360, which is not free. We’ve broken down the differences between the two versions elsewhere.

    Image showing audience-related data provided by GA4

    GA4’s audience overview shows visitors, sessions, session lengths, bounce rates, and user engagement data. (Image source)

     

    Why Google Analytics : It’s great for gauging the effectiveness of marketing campaigns, tracking goal completions (purchases, cart additions, etc.) and spotting trends and patterns in user engagement.

    Standout features include built-in automation, customisable conversion goals, data drill-down functionality, detailed web acquisition metrics, media spend ROI calculations and out-of-the-box web analytics reporting.

    Integrations include all major CRM platforms, CallRail, DoubleClick DCM, Facebook, Hootsuite, Marketo, Shopify, VWO, WordPress, Zapier and Zendesk, among many others.

    Pricing is free for the basic version (Google Analytics 4) and scales based on features and data volume. The advanced features (in Google Analytics 360) are pitched at enterprises, and pricing is custom.

    Strengths

    • Free to start
    • Multiple website management
    • Traffic source details
    • Up-to-date traffic data

    Community critiques 

    • Steep learning curve 
    • Data sampling

    4. Adobe Analytics – Best for predictive analytics

    A fully configured Adobe Analytics implementation is the Swiss army knife of analytics tools. It begins with web analytics, adds product analytics, and then wraps it up nicely with predictive analytics.

    Unlike all the Amplitude alternatives here, there’s no free version. Adobe Analytics has a complicated pricing matrix with options like website analytics, marketing analytics, attribution, and predictive analytics. It also has a wide range of customisation options that will appeal to large businesses. But for smaller organisations, it may all be a bit too much.

    Mixpanel allows you to play around filters and views to reveal and chart some useful customer trends. (Image source)

    Screenshot categorising online orders by marketing channel

    Adobe Analytics’ cross-channel attribution ties actions from different channels into a single customer journey. (Image source)

     

    Why Adobe Analytics : For current Adobe customers, this is a logical next step. Either way, Adobe Analytics can combine, evaluate, and analyse data from any part of the customer journey. It analyses that data with predictive intelligence to provide insights to enhance customer experiences.

     

    Standout features include AI-powered prediction analysis, attribution analysis, multi-channel data collection, segmentation and detailed customer journey analytics, product analytics and web analytics.

     

    Integrations are available through the Adobe Experience Cloud Exchange. Adobe Analytics also supports data exchange with brands such as BrightEdge, Branch.io, Google Ads, Hootsuite, Invoca, Salesforce and over 200 other integrations.

     

    Pricing starts at $500 monthly, but prospective customers are encouraged to contact the company for a needs-based quotation.

     

    Strengths

    • Drag-and-drop interface
    • Flexible segmentation 
    • Easy-to-create conversion funnels
    • Threshold-based alerts and notifications

    Community critiques 

    • No free version
    • Lack of technical support
    • Steep learning curve

    5. Umami – Best lightweight tool for web analytics

    The second of our open-source analytics solutions is Umami, a favourite in the software development community. Like Matomo, it’s a powerful and privacy-focused alternative that offers complete data control and respects user privacy. It’s also available as a cloud-based freemium plan or as a self-hosted solution.

     

    Image showing current user traffic and hourly traffic going back 24 hours

    Umami’s dashboard reveals the busiest times of day and which pages are visited when.(Image source)

     

    Why Umami : Unami has a clear and simple user interface (UI) that lets you measure important metrics such as page visits, referrers, and user agents. It also features event tracking, although some reviewers complain that it’s quite limited.

    Standout features can be summed up in five words : privacy, simplicity, lightweight, real-time, and open-source. Unami’s UI is clean, intuitive and modern, and it doesn’t slow down your website. 

    Integrations include plugins for VuePress, Gatsby, Craft CMS, Docusaurus, WordPress and Publii, and a module for Nuxt. Unami’s API communicates with Javascript, PHP Laravel and Python.

    Pricing is free for up to 100k monthly events and three websites, but with limited support and data retention restrictions. The Pro plan costs $20 a month and gives you unlimited websites and team members, a million events (plus $0.00002 for each event over that), five years of data and email support. Their Enterprise plan is priced custom.

    Strengths

    • Freemium plan
    • Open-source
    • Lightweight 

    Community critiques 

    • Limited support options
    • Data retention restrictions
    • No funnel functionality

    6. Heap – Best for automatic data capture

    Product analytics with a twist is a good description of Heap. It features event auto-capture to track user interactions across all touchpoints in the user journey. This lets you fully understand how and why customers engage with your product and website. 

    Using a single Javascript snippet, Heap automatically collects data on everything users do, including how they got to your website. It also helps identify how different cohorts engage with your product, providing the critical insights teams need to boost conversion rates.

    Image showing funnel and path analysis data and insights

    Heap’s journeys feature combines funnel and path analysis. (Image source)

     

    Why Heap : The auto-capture functionality solves a major shortcoming of many product analytics tools — manual tracking. Instead of having to set up manual tags on events, Heap automatically captures all data on user activity from the start. 

    Standout features include event auto-capture, session replay, heatmaps, segments (or cohorts) and journeys, the last of which combines the functions of funnel and path analysis tools into a single feature.

    Integrations include AWS, Google, Microsoft Azure, major CRM platforms, Snowflake and many other data manipulation platforms.

    Pricing is quote-based across all payment tiers. There is also a free plan and a 14-day free trial.

    Strengths

    • Session replay
    • Heatmaps 
    • User segmentation
    • Simple setup 
    • Event auto-capture 

    Community critiques 

    • No A/B testing functionality
    • No GDPR compliance support

    Choosing the best solution for your team

    When selecting a tool, it’s crucial to understand how product analytics and web analytics solutions differ. 

    Product analytics tools track users or accounts and record the features they use, the funnels they move through, and the cohorts they’re part of. Web analytics tools focus more on sessions than users because they’re interested in data that can help improve website usage. 

    Some tools combine product and web analytics to do both of these jobs.

    Area of focus

    Product analytics tools track user behaviour within SaaS- or app-based products. They’re helpful for analysing features, user journeys, engagement metrics, product development and iteration. 

    Web analytics tools analyse web traffic, user demographics, and traffic sources. They’re most often used for marketing and SEO insights.

    Level of detail

    Product analytics tools provide in-depth tracking and analysis of user interactions, feature usage, and cohort analysis.

    Web analytics tools provide broader data on page views, bounce rates, and conversion tracking to analyse overall site performance.

    Whatever tools you try, your first step should be to search for reviews online to see what people who’ve used them think about them. There are some great review sites you can try. See what people are saying on Capterra, G2, Gartner Peer Insights, or TrustRadius

    Use Matomo to power your web and app analytics

    Web and product analytics is a competitive field, and there are many other tools worth considering. This list is a small cross-section of what’s available.

    That said, if you have concerns about privacy and costs, consider choosing Matomo. Start your 21-day free trial today.

  • MOV to ACVHD conversion via Spring Boot and FFmpeg leads to file system error

    31 décembre 2024, par epicUsername

    I am experiencing an issue on a personal project that seeks to convert HEIC to JPG files and MOV files to AVCHD format. The HEIC to JPG conversion works, but the MOV to AVCHD does not, which is where my problems lie.

    


    The intent is to do this with Spring Boot and FFmpeg, using a simple interface done in WindowBuilder.

    


    The relevant bits are the pom file :

    


        <dependencies>&#xA;    &#xA;        &#xA;        <dependency>&#xA;            <groupid>jmagick</groupid>&#xA;            <artifactid>jmagick</artifactid>&#xA;            <version>6.6.9</version>&#xA;        </dependency>&#xA;&#xA;        &#xA;        <dependency>&#xA;            <groupid>net.java.dev.jna</groupid>&#xA;            <artifactid>jna</artifactid>&#xA;            <version>5.7.0</version> &#xA;        </dependency>&#xA;        <dependency>&#xA;            <groupid>net.java.dev.jna</groupid>&#xA;            <artifactid>jna-platform</artifactid>&#xA;            <version>5.7.0</version>&#xA;        </dependency>&#xA;        &#xA;        &#xA;&#xA;&#xA;        <dependency>&#xA;            <groupid>org.bytedeco</groupid>&#xA;            <artifactid>ffmpeg</artifactid>&#xA;            <version>7.1-1.5.11</version>&#xA;        </dependency>&#xA;        <dependency>&#xA;            <groupid>org.bytedeco</groupid>&#xA;            <artifactid>javacv</artifactid>&#xA;            <version>1.5.11</version>&#xA;        </dependency>&#xA;        <dependency>&#xA;            <groupid>org.bytedeco</groupid>&#xA;            <artifactid>ffmpeg-platform</artifactid>&#xA;            <version>7.1-1.5.11</version>&#xA;        </dependency>&#xA;        &#xA;        <dependency>&#xA;            <groupid>org.bytedeco</groupid>&#xA;            <artifactid>javacpp</artifactid>&#xA;            <version>1.5.11</version>&#xA;        </dependency>&#xA;    </dependencies>&#xA;&#xA;

    &#xA;

    and the main file with the event handling for the application, based on the interface :

    &#xA;

    package home.multimeida.mmconverter;&#xA;&#xA;imports...&#xA;&#xA;public class MMConverterInterface extends JFrame {&#xA;&#xA;    public static void main(String[] args) {&#xA;        &#xA;        &#xA;        try {&#xA;            System.setProperty("jna.library.path", "absolute/path/to/gstreamer/bin");&#xA;            // Gst.init("GStreamer Test");&#xA;            System.out.println("GStreamer initialized successfully.");&#xA;        } catch (Exception e) {&#xA;            e.printStackTrace();&#xA;            System.out.println("Failed to initialize GStreamer.");&#xA;        }&#xA;        EventQueue.invokeLater(new Runnable() {&#xA;            public void run() {&#xA;                try {&#xA;                    MMConverterInterface frame = new MMConverterInterface();&#xA;                    frame.setVisible(true);&#xA;                } catch (Exception e) {&#xA;                    e.printStackTrace();&#xA;                }&#xA;            }&#xA;        });&#xA;    }&#xA;&#xA;    /**&#xA;     * Create the frame.&#xA;     */&#xA;    public MMConverterInterface() {&#xA;        &#xA;        // convert button&#xA;        &#xA;        btnConvert.addActionListener(e -> {&#xA;            &#xA;            try {&#xA;                &#xA;                if (sourceFileLabel.getText().equals("No file chosen...") || destinationFolderLabel.getText().equals("No folder selected...")) {&#xA;                    JOptionPane.showMessageDialog(null, "Please select both an input file and a save location.", "Validation Error", JOptionPane.WARNING_MESSAGE);&#xA;                    return;&#xA;                }&#xA;                 &#xA;                File sourceFile = new File(sourceFileLabel.getText());&#xA;                File destinationFile;&#xA;                 &#xA;                if (rdbtnNewRadioButton.isSelected()) {&#xA;                    &#xA;                    System.out.println("Converting HEIC to JPG...");&#xA;                        &#xA;                    String outputFileName = sourceFile.getName().replaceFirst("[.][^.]&#x2B;$", ".jpg");&#xA;                    &#xA;                    // Call your conversion logic here&#xA;                    &#xA;                    destinationFile = new File(destinationFolderLabel.getText(), outputFileName);&#xA;                    &#xA;                    convertHeicToJpg(sourceFile, destinationFile);&#xA;                    &#xA;                } else if (rdbtnNewRadioButton_1.isSelected()) {&#xA;                    &#xA;                    if (sourceFileLabel.getText().equals("No file chosen...") || destinationFolderLabel.getText().equals("No folder selected...")) {&#xA;                        JOptionPane.showMessageDialog(null, "Please select both an input file and a save location.", "Validation Error", JOptionPane.WARNING_MESSAGE);&#xA;                        return;&#xA;                    }&#xA;                    &#xA;                     // Validate source file&#xA;                    if (!sourceFile.exists() || !sourceFile.canRead()) {&#xA;                        JOptionPane.showMessageDialog(null, "Source file does not exist or is not readable.", "File Error", JOptionPane.ERROR_MESSAGE);&#xA;                        return;&#xA;                    }&#xA;                    &#xA;                    // Validate destination folder&#xA;                    String destinationPath = destinationFolderLabel.getText();&#xA;                    if (destinationPath == null || destinationPath.isEmpty() || !(new File(destinationPath).isDirectory())) {&#xA;                        JOptionPane.showMessageDialog(null, "Invalid destination folder.", "File Error", JOptionPane.ERROR_MESSAGE);&#xA;                        return;&#xA;                    }&#xA;                    &#xA;                    System.out.println("Converting MOV to AVCHD...");&#xA;                    &#xA;                    String currentDate = new SimpleDateFormat("yyyyMMdd").format(new Date());&#xA;&#xA;                    // Extract the file name without the extension&#xA;                    String baseName = sourceFile.getName().replaceFirst("[.][^.]&#x2B;$", "");&#xA;&#xA;                    // Sanitize the base name (replace invalid characters with &#x27;_&#x27;)&#xA;                    baseName = baseName.replaceAll("[^a-zA-Z0-9-_]", "_");&#xA;                    &#xA;                    String sanitizedFileName = baseName &#x2B; "_" &#x2B; currentDate;&#xA;                    sanitizedFileName = sanitizedFileName.replaceAll("[^a-zA-Z0-9._-]", "_"); // Allow alphanumeric, &#x27;-&#x27;, &#x27;_&#x27;, and &#x27;.&#x27;&#xA;&#xA;                    destinationFile = new File(destinationPath, sanitizedFileName);&#xA;                    &#xA;                    &#xA;                    /*&#xA;                    // Ensure the destination file is writable&#xA;                    if (!destinationFile.canWrite()) {&#xA;                        JOptionPane.showMessageDialog(null, "Output file is not writable.", "File Error", JOptionPane.ERROR_MESSAGE);&#xA;                        return;&#xA;                    }&#xA;                    */&#xA;                   &#xA;&#xA;                    convertMovToAvchd(sourceFile, destinationFile);&#xA;                    &#xA;                } else {&#xA;                    &#xA;                    JOptionPane.showMessageDialog(null, "Please select a conversion type.");&#xA;                    &#xA;                }&#xA;                &#xA;            } catch (Exception ex) {&#xA;                &#xA;                JOptionPane.showMessageDialog(null, "Error: " &#x2B; ex.getMessage(), "Conversion Error", JOptionPane.ERROR_MESSAGE);&#xA;                ex.printStackTrace();&#xA;            }&#xA;            &#xA;            &#xA;        });&#xA;        &#xA;        // cancel button:&#xA;        &#xA;        btnCancel.addActionListener(e -> {&#xA;            System.out.println("Operation canceled.");&#xA;            System.exit(0); // Close the application&#xA;        });&#xA;&#xA;    }&#xA;    &#xA;    public void convertMovToAvchd(File sourceFile, File destinationFile) {&#xA;        avutil.av_log_set_level(avutil.AV_LOG_DEBUG);&#xA;        &#xA;        &#xA;&#xA;        AVFormatContext inputFormatContext = null;&#xA;        AVFormatContext outputFormatContext = new AVFormatContext(null);&#xA;        AVCodecContext inputCodecContext = null;&#xA;        AVCodecContext outputCodecContext = null;&#xA;&#xA;        try {&#xA;            // Validate input file&#xA;            if (!sourceFile.exists() || !sourceFile.canRead()) {&#xA;                System.out.println("Source file does not exist or is not readable: " &#x2B; sourceFile.getAbsolutePath());&#xA;                return;&#xA;            }&#xA;            &#xA;            // Validate output file path using the validateFileCreation method&#xA;            if (!validateFileCreation(destinationFile)) {&#xA;                return; // Exit if destination file validation fails&#xA;            }&#xA;&#xA;            // Validate output file path&#xA;            if (destinationFile.getParentFile() == null || !destinationFile.getParentFile().exists()) {&#xA;                System.out.println("Output directory does not exist: " &#x2B; destinationFile.getParentFile());&#xA;                return;&#xA;            }&#xA;            if (!destinationFile.getParentFile().canWrite()) {&#xA;                System.out.println("Output directory is not writable: " &#x2B; destinationFile.getParentFile());&#xA;                return;&#xA;            }&#xA;&#xA;            // Open input file&#xA;            inputFormatContext = avformat.avformat_alloc_context();&#xA;            if (avformat.avformat_open_input(inputFormatContext, sourceFile.getAbsolutePath(), null, null) &lt; 0) {&#xA;                System.out.println("Failed to open input file: " &#x2B; sourceFile.getAbsolutePath());&#xA;                return;&#xA;            }&#xA;&#xA;            // Find stream information&#xA;            if (avformat.avformat_find_stream_info(inputFormatContext, (PointerPointer) null) &lt; 0) {&#xA;                System.out.println("Failed to retrieve input stream information.");&#xA;                return;&#xA;            }&#xA;&#xA;            // Find video stream&#xA;            int videoStreamIndex = avformat.av_find_best_stream(inputFormatContext, avutil.AVMEDIA_TYPE_VIDEO, -1, -1, (AVCodec) null, 0);&#xA;            if (videoStreamIndex &lt; 0) {&#xA;                System.out.println("Failed to find video stream in input file.");&#xA;                return;&#xA;            }&#xA;&#xA;            // Initialize input codec context&#xA;            inputCodecContext = avcodec.avcodec_alloc_context3(null);&#xA;            avcodec.avcodec_parameters_to_context(inputCodecContext, inputFormatContext.streams(videoStreamIndex).codecpar());&#xA;&#xA;            AVCodec decoder = avcodec.avcodec_find_decoder(inputCodecContext.codec_id());&#xA;            if (decoder == null || avcodec.avcodec_open2(inputCodecContext, decoder, (PointerPointer) null) &lt; 0) {&#xA;                System.out.println("Failed to open video decoder.");&#xA;                return;&#xA;            }&#xA;&#xA;            // Allocate output format context&#xA;            if (avformat.avformat_alloc_output_context2(outputFormatContext, null, "mpegts", destinationFile.getAbsolutePath()) &lt; 0) {&#xA;                System.out.println("Failed to allocate output format context.");&#xA;                return;&#xA;            }&#xA;&#xA;            // Initialize output codec&#xA;            AVCodec encoder = avcodec.avcodec_find_encoder_by_name("mpeg2video");&#xA;            if (encoder == null) {&#xA;                System.out.println("Failed to find MPEG2 video encoder.");&#xA;                return;&#xA;            }&#xA;&#xA;            outputCodecContext = avcodec.avcodec_alloc_context3(encoder);&#xA;            if (outputCodecContext == null) {&#xA;                System.out.println("Failed to allocate output codec context.");&#xA;                return;&#xA;            }&#xA;            &#xA;            if ((outputFormatContext.oformat().flags() &amp; avformat.AVFMT_GLOBALHEADER) != 0) {&#xA;                outputCodecContext.flags(outputCodecContext.flags() | avcodec.AV_CODEC_FLAG_GLOBAL_HEADER);&#xA;            }&#xA;&#xA;&#xA;            //outputCodecContext.codec_id(avcodec.AV_CODEC_ID_MPEG2VIDEO);&#xA;            outputCodecContext.codec_id(encoder.id());&#xA;            outputCodecContext.codec_type(avutil.AVMEDIA_TYPE_VIDEO);&#xA;            outputCodecContext.width(1920);&#xA;            outputCodecContext.height(1080);&#xA;            outputCodecContext.pix_fmt(avutil.AV_PIX_FMT_YUV420P);&#xA;            outputCodecContext.time_base(avutil.av_make_q(1, 25));&#xA;            outputCodecContext.bit_rate(4000000);&#xA;            outputCodecContext.gop_size(12);&#xA;&#xA;            if ((outputFormatContext.oformat().flags() &amp; avformat.AVFMT_GLOBALHEADER) != 0) {&#xA;                outputCodecContext.flags(outputCodecContext.flags() | avcodec.AV_CODEC_FLAG_GLOBAL_HEADER);&#xA;            }&#xA;&#xA;            &#xA;            &#xA;            if (avcodec.avcodec_open2(outputCodecContext, encoder, (PointerPointer) null) &lt; 0) {&#xA;                System.out.println("Failed to open video encoder.");&#xA;                return;&#xA;            }&#xA;&#xA;            // Create output stream&#xA;            AVStream videoStream = avformat.avformat_new_stream(outputFormatContext, encoder);&#xA;            if (videoStream == null) {&#xA;                System.out.println("Failed to create video stream.");&#xA;                return;&#xA;            }&#xA;&#xA;            avcodec.avcodec_parameters_from_context(videoStream.codecpar(), outputCodecContext);&#xA;            &#xA;            System.out.println("Destination file path before trying to open the file is: " &#x2B; destinationFile);&#xA;&#xA;            if ((outputFormatContext.oformat().flags() &amp; avformat.AVFMT_NOFILE) == 0) {&#xA;                // Ensure the output path has the correct extension&#xA;                String outputPath = destinationFile.getAbsolutePath().replace("\\", "/") &#x2B; ".avchd";&#xA;                System.out.println("Normalized output path: " &#x2B; outputPath);&#xA;&#xA;                // Try opening the output file&#xA;                int ret = avformat.avio_open(outputFormatContext.pb(), outputPath, avformat.AVIO_FLAG_WRITE);&#xA;                if (ret &lt; 0) {&#xA;                    BytePointer errorBuffer = new BytePointer(avutil.AV_ERROR_MAX_STRING_SIZE);&#xA;                    avutil.av_strerror(ret, errorBuffer, errorBuffer.capacity());&#xA;                    System.out.println("Failed to open output file: " &#x2B; errorBuffer.getString());&#xA;                    return;&#xA;                }&#xA;            }&#xA;&#xA;&#xA;            // Write header&#xA;            if (avformat.avformat_write_header(outputFormatContext, (PointerPointer) null) &lt; 0) {&#xA;                System.out.println("Failed to write header to output file.");&#xA;                return;&#xA;            }&#xA;&#xA;&#xA;            // Packet processing loop&#xA;            AVPacket packet = new AVPacket();&#xA;            while (avformat.av_read_frame(inputFormatContext, packet) >= 0) {&#xA;                if (packet.stream_index() == videoStreamIndex) {&#xA;                    if (avcodec.avcodec_send_packet(inputCodecContext, packet) >= 0) {&#xA;                        AVFrame frame = avutil.av_frame_alloc();&#xA;                        while (avcodec.avcodec_receive_frame(inputCodecContext, frame) >= 0) {&#xA;                            if (avcodec.avcodec_send_frame(outputCodecContext, frame) >= 0) {&#xA;                                AVPacket encodedPacket = new AVPacket();&#xA;                                while (avcodec.avcodec_receive_packet(outputCodecContext, encodedPacket) >= 0) {&#xA;                                    encodedPacket.stream_index(videoStream.index());&#xA;                                    avformat.av_interleaved_write_frame(outputFormatContext, encodedPacket);&#xA;                                    avcodec.av_packet_unref(encodedPacket);&#xA;                                }&#xA;                            }&#xA;                            avutil.av_frame_unref(frame);&#xA;                        }&#xA;                        avutil.av_frame_free(frame);&#xA;                    }&#xA;                }&#xA;                avcodec.av_packet_unref(packet);&#xA;            }&#xA;&#xA;            // Write trailer&#xA;            avformat.av_write_trailer(outputFormatContext);&#xA;            System.out.println("Conversion completed successfully.");&#xA;            &#xA;            if (avcodec.avcodec_send_frame(outputCodecContext, null) >= 0) {&#xA;                AVPacket encodedPacket = new AVPacket();&#xA;                while (avcodec.avcodec_receive_packet(outputCodecContext, encodedPacket) >= 0) {&#xA;                    encodedPacket.stream_index(videoStream.index());&#xA;                    avformat.av_interleaved_write_frame(outputFormatContext, encodedPacket);&#xA;                    avcodec.av_packet_unref(encodedPacket);&#xA;                }&#xA;            }&#xA;&#xA;        } catch (Exception e) {&#xA;            e.printStackTrace();&#xA;        } finally {&#xA;            // Cleanup&#xA;            avcodec.avcodec_free_context(inputCodecContext);&#xA;            avcodec.avcodec_free_context(outputCodecContext);&#xA;            avformat.avformat_close_input(inputFormatContext);&#xA;&#xA;            if (outputFormatContext != null &amp;&amp; outputFormatContext.pb() != null) {&#xA;                avformat.avio_closep(outputFormatContext.pb());&#xA;            }&#xA;            avformat.avformat_free_context(outputFormatContext);&#xA;        }&#xA;    }&#xA;    &#xA;    private boolean validateFileCreation(File destinationFile) {&#xA;        // Check if the parent directory exists and is writable&#xA;        File parentDir = destinationFile.getParentFile();&#xA;        if (parentDir == null || !parentDir.exists()) {&#xA;            System.out.println("Parent directory does not exist: " &#x2B; parentDir);&#xA;            return false;&#xA;        }&#xA;        if (!parentDir.canWrite()) {&#xA;            System.out.println("Cannot write to parent directory: " &#x2B; parentDir);&#xA;            return false;&#xA;        }&#xA;&#xA;        // Check if the file exists and is writable&#xA;        if (destinationFile.exists()) {&#xA;            if (!destinationFile.canWrite()) {&#xA;                System.out.println("Destination file is not writable: " &#x2B; destinationFile);&#xA;                return false;&#xA;            }&#xA;        } else {&#xA;            // If the file doesn&#x27;t exist, try to create it to verify writability&#xA;            try {&#xA;                if (!destinationFile.createNewFile()) {&#xA;                    System.out.println("Unable to create destination file: " &#x2B; destinationFile);&#xA;                    return false;&#xA;                }&#xA;                // Delete the file after successful creation to avoid residual files&#xA;                destinationFile.delete();&#xA;            } catch (IOException e) {&#xA;                System.out.println("File creation failed: " &#x2B; e.getMessage());&#xA;                return false;&#xA;            }&#xA;        }&#xA;&#xA;        return true;&#xA;    }&#xA;    &#xA;}&#xA;&#xA;&#xA;

    &#xA;

    A few caveats :

    &#xA;

      &#xA;
    1. I did explore FFmpeg and GStreamer for this project. GStreamer was inconclusive, with available version for it that were too old for use with my current state of STS4.27 and Java 17, even if this version of Java is under long-term support...

      &#xA;

    2. &#xA;

    3. I've used AI to tell me about the options and suggest ways to build this thing, since multimedia handling is very far away from my skillset. I don't have a good conceptual grasp of video formats and how they transfrom from one to another.

      &#xA;

    4. &#xA;

    &#xA;

    The issue, as I have identified it, occurs at these lines :

    &#xA;

     // Ensure the destination file is writable&#xA;                    if (!destinationFile.canWrite()) {&#xA;                        JOptionPane.showMessageDialog(null, "Output file is not writable.", "File Error", JOptionPane.ERROR_MESSAGE);&#xA;                        return;&#xA;                    }&#xA;

    &#xA;

    ^^ And this, while temporarily commented out for testing, it meant to compensate for an issue that occurs here in the conversion function :

    &#xA;

     if ((outputFormatContext.oformat().flags() &amp; avformat.AVFMT_NOFILE) == 0) {&#xA;                // Ensure the output path has the correct extension&#xA;                String outputPath = destinationFile.getAbsolutePath().replace("\\", "/") &#x2B; ".avchd";&#xA;                System.out.println("Normalized output path: " &#x2B; outputPath);&#xA;&#xA;                // Try opening the output file&#xA;                int ret = avformat.avio_open(outputFormatContext.pb(), outputPath, avformat.AVIO_FLAG_WRITE);&#xA;                if (ret &lt; 0) {&#xA;                    BytePointer errorBuffer = new BytePointer(avutil.AV_ERROR_MAX_STRING_SIZE);&#xA;                    avutil.av_strerror(ret, errorBuffer, errorBuffer.capacity());&#xA;                    System.out.println("Failed to open output file: " &#x2B; errorBuffer.getString());&#xA;                    return;&#xA;                }&#xA;            }&#xA;

    &#xA;

    The idea here is that the avio_open() function requires the use of the a valid file path that it can open to be able to write it.

    &#xA;

    Padadoxically, the file conversion seems to work, but the project crashes with a fatal error in the console :

    &#xA;

    Selected file: E:\TestConveresions\sample_960x540.mov&#xA;Save location: E:\TestConveresions&#xA;Converting MOV to AVCHD...&#xA;Destination file path before trying to open the file is: E:\TestConveresions\sample_960x540_20241231&#xA;Normalized output path: E:/TestConveresions/sample_960x540_20241231.avchd&#xA;#&#xA;# A fatal error has been detected by the Java Runtime Environment:&#xA;#&#xA;#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffcffb0868b, pid=11020, tid=14436&#xA;#&#xA;# JRE version: OpenJDK Runtime Environment Temurin-21.0.5&#x2B;11 (21.0.5&#x2B;11) (build 21.0.5&#x2B;11-LTS)&#xA;# Java VM: OpenJDK 64-Bit Server VM Temurin-21.0.5&#x2B;11 (21.0.5&#x2B;11-LTS, mixed mode, emulated-client, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64)&#xA;# Problematic frame:&#xA;# C  0x00007ffcffb0868b&#xA;#&#xA;# No core dump will be written. Minidumps are not enabled by default on client versions of Windows&#xA;#&#xA;# An error report file with more information is saved as:&#xA;# E:\STS4 Workspace\MMConverter\hs_err_pid11020.log&#xA;[80.882s][warning][os] Loading hsdis library failed&#xA;#&#xA;# If you would like to submit a bug report, please visit:&#xA;#   https://github.com/adoptium/adoptium-support/issues&#xA;# The crash happened outside the Java Virtual Machine in native code.&#xA;# See problematic frame for where to report the bug.&#xA;#&#xA;[AVFormatContext @ 000002528adcea40] Opening &#x27;E:\TestConveresions\sample_960x540.mov&#x27; for reading&#xA;[file @ 000002528ae51c40] Setting default whitelist &#x27;file,crypto,data&#x27;&#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] Format mov,mp4,m4a,3gp,3g2,mj2 probed with size=2048 and score=100&#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] ISO: File Type Major Brand: qt  &#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] Unknown dref type 0x206c7275 size 12&#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] Processing st: 0, edit list 0 - media time: 2002, duration: 400410&#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] Offset DTS by 2002 to make first pts zero.&#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] Setting codecpar->delay to 2 for stream st: 0&#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] Before avformat_find_stream_info() pos: 1320742 bytes read:38225 seeks:1 nb_streams:1&#xA;[h264 @ 000002528ae62780] nal_unit_type: 7(SPS), nal_ref_idc: 3&#xA;[h264 @ 000002528ae62780] Decoding VUI&#xA;[h264 @ 000002528ae62780] nal_unit_type: 8(PPS), nal_ref_idc: 3&#xA;[h264 @ 000002528ae62780] nal_unit_type: 7(SPS), nal_ref_idc: 3&#xA;[h264 @ 000002528ae62780] Decoding VUI&#xA;[h264 @ 000002528ae62780] nal_unit_type: 8(PPS), nal_ref_idc: 3&#xA;[h264 @ 000002528ae62780] nal_unit_type: 6(SEI), nal_ref_idc: 0&#xA;[h264 @ 000002528ae62780] nal_unit_type: 5(IDR), nal_ref_idc: 3&#xA;[h264 @ 000002528ae62780] Format yuv420p chosen by get_format().&#xA;[h264 @ 000002528ae62780] Reinit context to 960x544, pix_fmt: yuv420p&#xA;[h264 @ 000002528ae62780] no picture &#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] All info found&#xA;[mov,mp4,m4a,3gp,3g2,mj2 @ 000002528adcea40] After avformat_find_stream_info() pos: 51943 bytes read:90132 seeks:2 frames:1&#xA;[h264 @ 000002528ae62780] nal_unit_type: 7(SPS), nal_ref_idc: 3&#xA;[h264 @ 000002528ae62780] Decoding VUI&#xA;[h264 @ 000002528ae62780] nal_unit_type: 8(PPS), nal_ref_idc: 3&#xA;[mpeg2video @ 000002528ae8e700] intra_quant_bias = 96 inter_quant_bias = 0&#xA;&#xA;

    &#xA;

    If I refer to the error log, I get this. It is partial, as I'm not sure SO will take all of it (quite long), but still might have enough to be relevant :

    &#xA;

    Host: Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz, 8 cores, 31G,  Windows 11 , 64 bit Build 26100 (10.0.26100.2454)&#xA;&#xA;&#xA;---------------  T H R E A D  ---------------&#xA;&#xA;Current thread (0x00000252d030b340):  JavaThread "AWT-EventQueue-0"        [_thread_in_native, id=14436, stack(0x000000a4e2b00000,0x000000a4e2c00000) (1024K)]&#xA;&#xA;Stack: [0x000000a4e2b00000,0x000000a4e2c00000],  sp=0x000000a4e2bfdf30,  free space=1015k&#xA;Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)&#xA;C  0x00007ffcffb0868b&#xA;&#xA;Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)&#xA;j  org.bytedeco.ffmpeg.global.avformat.avio_open(Lorg/bytedeco/ffmpeg/avformat/AVIOContext;Ljava/lang/String;I)I&#x2B;0&#xA;j  home.multimeida.mmconverter.MMConverterInterface.convertMovToAvchd(Ljava/io/File;Ljava/io/File;)V&#x2B;1120&#xA;j  home.multimeida.mmconverter.MMConverterInterface.lambda$2(Ljavax/swing/JRadioButton;Ljavax/swing/JRadioButton;Ljava/awt/event/ActionEvent;)V&#x2B;347&#xA;j  home.multimeida.mmconverter.MMConverterInterface$$Lambda&#x2B;0x000002528c0c7778.actionPerformed(Ljava/awt/event/ActionEvent;)V&#x2B;13&#xA;j  javax.swing.AbstractButton.fireActionPerformed(Ljava/awt/event/ActionEvent;)V&#x2B;84 java.desktop@21.0.5&#xA;j  javax.swing.AbstractButton$Handler.actionPerformed(Ljava/awt/event/ActionEvent;)V&#x2B;5 java.desktop@21.0.5&#xA;j  javax.swing.DefaultButtonModel.fireActionPerformed(Ljava/awt/event/ActionEvent;)V&#x2B;34 java.desktop@21.0.5&#xA;j  javax.swing.DefaultButtonModel.setPressed(Z)V&#x2B;117 java.desktop@21.0.5&#xA;j  javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Ljava/awt/event/MouseEvent;)V&#x2B;35 java.desktop@21.0.5&#xA;j  java.awt.Component.processMouseEvent(Ljava/awt/event/MouseEvent;)V&#x2B;64 java.desktop@21.0.5&#xA;j  javax.swing.JComponent.processMouseEvent(Ljava/awt/event/MouseEvent;)V&#x2B;23 java.desktop@21.0.5&#xA;J 2581 c1 java.awt.Component.processEvent(Ljava/awt/AWTEvent;)V java.desktop@21.0.5 (220 bytes) @ 0x00000252fa62719c [0x00000252fa627020&#x2B;0x000000000000017c]&#xA;J 2580 c1 java.awt.Container.processEvent(Ljava/awt/AWTEvent;)V java.desktop@21.0.5 (22 bytes) @ 0x00000252fa627d9c [0x00000252fa627cc0&#x2B;0x00000000000000dc]&#xA;J 2406 c1 java.awt.Component.dispatchEventImpl(Ljava/awt/AWTEvent;)V java.desktop@21.0.5 (785 bytes) @ 0x00000252fa670f14 [0x00000252fa670040&#x2B;0x0000000000000ed4]&#xA;J 2325 c1 java.awt.Container.dispatchEventImpl(Ljava/awt/AWTEvent;)V java.desktop@21.0.5 (129 bytes) @ 0x00000252fa64e93c [0x00000252fa64e8a0&#x2B;0x000000000000009c]&#xA;J 2608 c1 java.awt.LightweightDispatcher.retargetMouseEvent(Ljava/awt/Component;ILjava/awt/event/MouseEvent;)V java.desktop@21.0.5 (372 bytes) @ 0x00000252fa61c364 [0x00000252fa61b9e0&#x2B;0x0000000000000984]&#xA;J 2578 c1 java.awt.LightweightDispatcher.processMouseEvent(Ljava/awt/event/MouseEvent;)Z java.desktop@21.0.5 (268 bytes) @ 0x00000252fa628a54 [0x00000252fa6284c0&#x2B;0x0000000000000594]&#xA;J 2474 c1 java.awt.LightweightDispatcher.dispatchEvent(Ljava/awt/AWTEvent;)Z java.desktop@21.0.5 (73 bytes) @ 0x00000252fa699bbc [0x00000252fa699a60&#x2B;0x000000000000015c]&#xA;J 2325 c1 java.awt.Container.dispatchEventImpl(Ljava/awt/AWTEvent;)V java.desktop@21.0.5 (129 bytes) @ 0x00000252fa64e914 [0x00000252fa64e8a0&#x2B;0x0000000000000074]&#xA;J 2473 c1 java.awt.Window.dispatchEventImpl(Ljava/awt/AWTEvent;)V java.desktop@21.0.5 (23 bytes) @ 0x00000252fa699654 [0x00000252fa6994e0&#x2B;0x0000000000000174]&#xA;J 1838 c1 java.awt.EventQueue.dispatchEventImpl(Ljava/awt/AWTEvent;Ljava/lang/Object;)V java.desktop@21.0.5 (139 bytes) @ 0x00000252fa3bec64 [0x00000252fa3beb20&#x2B;0x0000000000000144]&#xA;J 1837 c1 java.awt.EventQueue$4.run()Ljava/lang/Void; java.desktop@21.0.5 (60 bytes) @ 0x00000252fa3c0504 [0x00000252fa3c0460&#x2B;0x00000000000000a4]&#xA;J 1836 c1 java.awt.EventQueue$4.run()Ljava/lang/Object; java.desktop@21.0.5 (5 bytes) @ 0x00000252fa3c0a04 [0x00000252fa3c09c0&#x2B;0x0000000000000044]&#xA;J 1778 c1 java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;Ljava/security/AccessControlContext;)Ljava/lang/Object; java.base@21.0.5 (22 bytes) @ 0x00000252fa4601d4 [0x00000252fa45ffa0&#x2B;0x0000000000000234]&#xA;J 1832 c1 java.awt.EventQueue.dispatchEvent(Ljava/awt/AWTEvent;)V java.desktop@21.0.5 (80 bytes) @ 0x00000252fa44f14c [0x00000252fa44eae0&#x2B;0x000000000000066c]&#xA;J 1846 c1 java.awt.EventDispatchThread.pumpOneEventForFilters(I)V java.desktop@21.0.5 (106 bytes) @ 0x00000252fa3ba544 [0x00000252fa3ba2e0&#x2B;0x0000000000000264]&#xA;j  java.awt.EventDispatchThread.pumpEventsForFilter(ILjava/awt/Conditional;Ljava/awt/EventFilter;)V&#x2B;35 java.desktop@21.0.5&#xA;j  java.awt.EventDispatchThread.pumpEventsForHierarchy(ILjava/awt/Conditional;Ljava/awt/Component;)V&#x2B;11 java.desktop@21.0.5&#xA;j  java.awt.EventDispatchThread.pumpEvents(ILjava/awt/Conditional;)V&#x2B;4 java.desktop@21.0.5&#xA;j  java.awt.EventDispatchThread.pumpEvents(Ljava/awt/Conditional;)V&#x2B;3 java.desktop@21.0.5&#xA;j  java.awt.EventDispatchThread.run()V&#x2B;9 java.desktop@21.0.5&#xA;v  ~StubRoutines::call_stub 0x00000252fa08100d&#xA;&#xA;siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), writing address 0x0000000000000000&#xA;&#xA;

    &#xA;

    If anyone has a perspective on this, it'd be appreciated.

    &#xA;

    The catch 22 in this project is that pre-creating the file is not a good idea, since avio_open has a purpose in-built method for that (I tried). Error checking everything about Java's File class in terms of setting pathways and creating and deleting files is not problematic. Likewise, permissions are all fine (Full Control in source and target folders) ; I've tested default C drive folders, which have restritions, to a separate volume and removable media, to no effect. Likewise, FFmpeg requires a forward slash, "/" in file paths, whereas Java does the backslash, generally. That's been handled with the replace method in the above conditioning, also to no effect.

    &#xA;

    The basic contradiction in the project seems to be that the error tries open a file that does not exist, with a valid source and destination file, and if I try to create a placeholder file wiht an acvhd extension at the event handling for the Convert button, it still errors out ; meanwhile, FFmpeg allegedly handles the file creation at its core, but requires a valid path to be passed ; I've tried with and without a filename, with and without an extension. I'm not able to resovle it.

    &#xA;

    The excessive error handling conditions are in an effort to isolate the problem, which I think I've done.

    &#xA;

    There also seems to be a compatibility between mpegts and acvhd, which is why I also had that format specified in the conversion function, without result.

    &#xA;

    I also have the idea to be able to do this without having to install any libraries locally or having to set path variables, which is an aspect that both GStreamer and FFmpeg have.

    &#xA;

    Nearest suggestion I've found is this : integrate ffmpeg with spring boot

    &#xA;

    AI remains hopeless for resolving this issue.

    &#xA;